Function 有多少个参数接受Haskell的foldr函数?

Function 有多少个参数接受Haskell的foldr函数?,function,haskell,arguments,fold,Function,Haskell,Arguments,Fold,我是哈斯克尔的新手,我正在读这本书。在本书的第4章中,作者要求作为练习,使用fold重写groupBy函数。该书的一位读者(屋大维·沃伊格)给出了以下解决方案: theCoolGroupBy :: (a -> a -> Bool) -> [a] -> [[a]] theCoolGroupBy eq xs = tail $ foldr step (\_ -> [[]]) xs $ (\_ -> False) where step x acc = \p

我是哈斯克尔的新手,我正在读这本书。在本书的第4章中,作者要求作为练习,使用fold重写groupBy函数。该书的一位读者(屋大维·沃伊格)给出了以下解决方案:


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
我的问题很简单:我知道foldr有3个参数:一个函数、一个初始值和一个列表。但在代码的第二行,foldr接受4个参数为什么会发生这种情况?
谢谢。

在本例中,
foldr
用于构建函数
(\ \ \->False)
是该函数的参数。

Haskell中的所有函数只接受一个参数。当我们有一个类型为
a->b->c
的函数时,编写
a->(b->c)
只是一种较短的方法,即函数,它接受一个参数,生成一个接受另一个参数的函数。有关更多信息,请参阅


在本例中,请参阅@sepp2k的答案
foldr
生成一个函数,它需要另一个(“第4”)参数。

在这种情况下,我认为最好查看
foldr
的类型签名:

foldr :: (a -> b -> b) -> b -> [a] -> b
为了将其与我们的表达式相匹配(为了清楚起见,添加了括号):

foldr
的第二个参数的类型与其结果相同。在本例中,第二个参数是一个函数。在本例中,这意味着带有3个参数的
foldr
表达式将是一个函数


您看到的foldr函数的第四个参数也可以被认为是foldr结果的第一个参数

Scott的回答是正确的,
foldr
的结果是一个函数,所以这就是为什么
foldr
似乎需要4个参数。
foldr
函数有3个参数(函数、基、列表):

这里我只举一个不那么复杂的例子:

inc :: Int -> (Int -> Int)
inc v = \x -> x + v

test = inc 2 40  -- output of test is 42
在上面的代码中,
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
圆括号可以用来强调返回值是一个函数,但在功能上与上述代码相同:

*Main> (inc 2) 40
42
附:我是原始评论的作者:)

*Main> :type inc
inc :: Int -> Int -> Int
*Main> :type inc 2
inc 2 :: Int -> Int
*Main> :type inc 2 40                                                        
inc 2 40 :: Int
*Main> (inc 2) 40
42