Search code examples
functionhaskellargumentsfold

How many arguments takes the foldr function of Haskell?


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.


Solution

  • 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 :)