1

入力としてリストを取得するハスケルのハミング関数を書いてみたいと思います。私はすでにこれを持っています:Haskellのリストを使ったハミング

merge :: [Integer] -> [Integer] -> [Integer] 
    merge (x:xs)(y:ys) 
     | x == y = x : merge xs ys 
     | x < y = x : merge xs (y:ys) 
     | otherwise = y : merge (x:xs) ys 


hamming :: [Integer] 
hamming 
    = 1 : merge (map (2*) hamming) (merge (map (3*) hamming) (map (5*) hamming)) 

これは簡単でした。しかし、今私は入力としてハミング[4,6,7,9]のようなものが欲しいです。実際の入力は1ですが、入力はリストでなければならず、リストにあるすべての数字はハミングリストにあります。もちろん、2x 3xと5xがリストに含まれています。

私はちょうどリストをテストするために

"hamming (x:xs) = x : merge (map (2*) hamming) (merge (map (3*) hamming) (map (5*) hamming))"のようなものを書いたが、それは動作しません。

+0

'map(3 *)hamming'とは何でしょうか?関数(?!)の*要素*に3を掛けたいとしますか? –

答えて

1

これはduplicateですが、どのように解決策に到達できるかを示します。重複して表示されます。ここで私の焦点は、その目的地ではなく旅にもっとなるでしょう。試しました

hamming (x:xs) 
    = 1 : merge (map (2*) hamming) (merge (map (3*) hamming) (map (5*) hamming)) 

ここでは何が起こっていますか?それは機能ですか?リスト?それはすべてここで混乱している。それは混乱です。あなたは、リスト定義を関数に変換したいとします。それをhamming [2,3,5]と呼んでいます。しかし、その後map式に入るはずですか?関数呼び出しhamming [2,3,5]も同様ですか?

しかし、我々は明確に、いくつかの別々の場所で、ここで同じリストを使用しているとしてそれは、目的を台無しにしてしまうが、それぞれに独自のポインタを維持し、3(または多分もっと...map秒、すなわち共有シーケンス。たとえ同等のものであっても、別々の関数呼び出しを行うことは、同じリストであっても3つの独立したリストを生成します(ほぼ確実に)。そして、それはではなく、ここに必要なものです(これは実際に楽しい演習です;試してみて、どれくらい遅く、メモリが空いているかを見てください)。

だから、あなたの懸念を分けてください!最初

hamming (x:xs) = h where 
    h = 1 : merge (map (2*) h) (merge (map (3*) h) (map (5*) h)) 

(まだ無効)として再書き込み今

hamming :: [Integer] -> [Integer] 
hamming [2,3,5] = h where 
    h = 1 : merge (map (2*) h) (merge (map (3*) h) (map (5*) h)) 
    = 1 : merge (map (2*) h) (merge (map (3*) h) (merge (map (5*) h) [])) 
つまり、あなたがそれになりたいものは何でも、 hは、共有リストであり、あなたはあなたの関数を作るために自由を持っている、 hammingある

 = 1 : foldr merge [] [map (p*) h | p <- [2,3,5]] 

 g a (g b (g c (... (g n z) ...))) 
    = 
     foldr g z [a,b,c,...,n] 
理由

それは、あなたの答え、パラメタのいくつかの世俗的な名前の変更までです。

マージそのままの刺激的であること、重複をスキップするように想定されていない「マージ」として、unionとしてあなたmerge機能の名前を変更することを忘れないでください。そして、すべての定義をファイルの同じインデントレベルから開始してください。