Dra*_*gno 6 haskell arguments function fold
我是Haskell的新手,我正在阅读"Real World Haskell"这本书 .在本书的第4章中,作者要求使用fold重写groupBy函数.本书的一位读者(Octavian Voicu)给出了以下解决方案:
theCoolGroupBy :: (a -> a -> Bool) -> [a] -> [[a]]
theCoolGroupBy eq xs = tail $ foldr step (\_ -> [[]]) xs $ (\_ -> False)
where step x acc = \p -> if p x then rest p else []:rest (eq x)
where rest q = let y:ys = acc q in (x:y):ys
Run Code Online (Sandbox Code Playgroud)
我的问题很简单:我知道foldr有3个参数:一个函数,一个初始值和一个列表.但在代码的第二行,foldr需要4个参数.为什么会这样? 谢谢.
在这种情况下,我认为最好看一下类型签名foldr
:
foldr :: (a -> b -> b) -> b -> [a] -> b
Run Code Online (Sandbox Code Playgroud)
并将其与我们所拥有的表达式相匹配(为了清楚起见,添加了括号):
(foldr step (\_ -> [[]]) xs) (\_ -> False)
Run Code Online (Sandbox Code Playgroud)
第二个参数foldr
与其结果的类型相同.在这种情况下,第二个参数是一个函数.在这种情况下,这意味着foldr
带有3个参数的表达式将是一个函数.
你认为是foldr函数的第四个参数也可以被认为是foldr结果的第一个参数!
小智 2
Scott 的答案是正确的, 的结果foldr
是一个函数,所以这就是为什么它看起来foldr
需要 4 个参数。这些foldr
函数需要 3 个参数(函数、基数、列表):
*Main> :type foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
Run Code Online (Sandbox Code Playgroud)
我在这里举一个不太复杂的例子:
inc :: Int -> (Int -> Int)
inc v = \x -> x + v
test = inc 2 40 -- output of test is 42
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,inc
接受一个参数 ,v
并返回一个将其参数递增 的函数v
。
如下所示, 的返回类型inc 2
是一个函数,因此可以简单地将其参数添加在末尾:
*Main> :type inc
inc :: Int -> Int -> Int
*Main> :type inc 2
inc 2 :: Int -> Int
*Main> :type inc 2 40
inc 2 40 :: Int
Run Code Online (Sandbox Code Playgroud)
可以使用括号来强调返回值是一个函数,但在功能上它与上面的代码相同:
*Main> (inc 2) 40
42
Run Code Online (Sandbox Code Playgroud)
PS:我是原评论的作者:)