How many arguments takes the foldr function of Haskell?

不想你离开。 提交于 2019-12-08 21:41:27

问题


I am new to Haskell and I am reading the book "Real World Haskell". In the Chapter 4 of the book the author asks as an exercise to rewrite the groupBy function using fold. One of the readers of the book (Octavian Voicu ) gave the following solution:


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

My question is simple: I know that foldr takes 3 arguments: a function, an initial value and a list. But in the second line of the code foldr takes 4 arguments. Why this happens? Thank you.


回答1:


Scott's answer is correct, the result of the foldr is a function, so this is why it seems that foldr takes 4 arguments. The foldr functions does take 3 arguments (function, base, list):

*Main> :type foldr
foldr :: (a -> b -> b) -> b -> [a] -> b

I'll just give here an example that is less complex:

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

test = inc 2 40  -- output of test is 42

In the above code, inc takes one argument, v, and returns a function that increments its argument by v.

As we can see below, the return type of inc 2 is a function, so its argument can simply be added at the end:

*Main> :type inc
inc :: Int -> Int -> Int
*Main> :type inc 2
inc 2 :: Int -> Int
*Main> :type inc 2 40                                                        
inc 2 40 :: Int

Parentheses could be used to emphasize that the return value is a function, but functionally it is identical to the above code:

*Main> (inc 2) 40
42

PS: I'm the author of the original comment :)




回答2:


In this situation, I think it is best to look at the type signature of foldr:

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

and to match that to the expression we have (with added parenthesis for clarity):

(foldr step (\_ -> [[]]) xs) (\_ -> False)

The second argument of foldr is the same type as its result. In this case the second argument is a function. In this case, this means that the foldr expression with 3 arguments will be a function.

What you see to be the 4th argument of the foldr function could also be thought of as the 1st argument of the foldr result!




回答3:


All functions in Haskell take just one argument. When we have a function with type a -> b -> c, it is just a shorter way to write a -> (b -> c), i.e. a function, which takes one argument and produces a function which takes another argument. See Currying for more information.

In this case, see the @sepp2k's answer. foldr produces a function and it needs another ("the 4th") argument.




回答4:


In this case foldr is used to build up a function. (\_ -> False) is the argument to that function.



来源:https://stackoverflow.com/questions/4733019/how-many-arguments-takes-the-foldr-function-of-haskell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!