Haskell用匿名函数折叠

时间:2012-09-29 10:35:20

标签: haskell anonymous-function fold

我遇到了一个Haskell基础问题:折叠+匿名函数

我正在使用foldl开发bin2dec程序 解决方案如下所示:

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

我理解foldl / foldr的基本概念,但我无法理解x y代表的参数。

2 个答案:

答案 0 :(得分: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的图表可能有助于建立更好的直觉。

foldl f z

考虑您的函数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个参数的函数,第一个是整数,第二个是一个字符并返回一个整数。 所以在这种情况下x=0y='1'f x y = 0*2 + 1 = 1

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

现在再次应用f 1 '1'。这里x=1y='1' f x y = 1*2 + 1 = 3

= foldl f 3 [] 

foldl的第一个定义用于空列表。

= 3 

“11”的十进制表示形式。

答案 1 :(得分:2)

使用类型!您可以在GHCi中键入:t,然后输入任何函数或值以查看其类型。如果我们询问foldl

的类型,会发生什么
Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a

输入列表的类型为[b],因此它是b的列表。输出类型为a,这是我们要生成的。您还必须为折叠提供初始值,同样为a类型。该函数的类型为

a -> b -> a

第一个参数(a)是到目前为止计算的折叠值。第二个参数(b)是列表的下一个元素。所以在你的例子中

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

参数x是您目前已计算的二进制数,y是列表中的下一个字符('1''0'