3

Haskell の基本の 1 つに問題があります: Fold + 無名関数

でbin2decプログラムを開発していfoldlます。
解決策は次のようになります。

bin2dec :: String -> Int
bin2dec = foldl (\x y -> if y=='1' then x*2 + 1 else x*2) 0

foldl/の基本的な考え方はfoldr理解できますが、パラメータの意味がわかりませんx y

4

2 に答える 2

7

の種類を見るfoldl

foldl :: (a -> b -> a) -> a -> [b] -> a

検討foldl f z list

そのため、foldl は基本的にリスト (または折りたたみ可能なもの) に対して段階的に機能し、左から 1 つの要素を取得して適用f z elementし、残りの要素を折りたたみながら、次のステップで使用する新しい要素を取得します。基本的に、foldl の簡単な定義が理解の助けになるかもしれません。

 foldl f z []     = z
 foldl f z (x:xs) = foldl f (f z x) xs

Haskell wikiの図は、より良い直感を構築するのに役立つかもしれません。

フォールドル fz

あなたの関数f = (\x y -> if y=='1' then x*2 + 1 else x*2)を考えて、 のトレースを書いてみてくださいfoldl f 0 "11"。ここ"11"は同じです['1','1']

  foldl f 0 ['1','1'] 
= foldl f (f 0 '1') ['1']

ここで、f は 2 つの引数 (最初は整数、2 番目は文字) を取り、整数を返す関数です。だから この場合x=0そしてy='1', そうf x y = 0*2 + 1 = 1

= foldl f 1 ['1']
= foldl f (f 1 '1') []

もう一度適用しf 1 '1'ます。などx=1など。y='1'_f x y = 1*2 + 1 = 3

= foldl f 3 [] 

foldl空のリストの最初の定義を使用します。

= 3 

これは「11」の 10 進数表現です。

于 2012-09-29T10:52:14.133 に答える
2

タイプを使おう!:tGHCi に続けて任意の関数または値を入力すると、そのタイプを確認できます。に型を尋ねると、次のようになります。foldl

Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a

入力リストはタイプ[b]なので、bs のリストです。出力タイプはa、これから作成するものです。また、タイプのフォールドの初期値も指定する必要がありますa。関数は型です

a -> b -> a

最初のパラメーター ( a) は、これまでに計算されたフォールドの値です。2 番目のパラメーター ( b) は、リストの次の要素です。だからあなたの例では

\x y -> if y == '1' then x * 2 + 1 else x * 2

パラメータxは、これまでに計算した 2 進数yで、リスト内の次の文字 ( a'1'または a '0') です。

于 2012-09-29T10:45:40.243 に答える