Search code examples
haskellfold

Using foldr with only two parameters


I've got a few exercises to prepare for the exam in Haskell/Prolog.

One Haskell task is to rewrite the function below:

original :: [Integer] -> Integer
original [] = 0
original (x:xs) | x < 20    = 5 * x - 3 + original xs
                | otherwise = original xs

But the condition is that I am only allowed to remove the two "undifined" in the scheme below:

alternative :: [Integer] -> Integer
alternative = foldr undefined undefined

My problem is that I dont know how this could match the normal foldr structure with 3 parameters (function, "start value" or how is it called?,list)?

Maybe an equivalent example would be helpfull, not the full soultion please!

Futhermore I am not allowed to use "let" or "where".

Thank you for any help!

Sooo... I just followed the idea from @hugo to just first complete the task on the "normal" way, which works but is not allowed by our university correction tool:

alternative :: [Integer] -> Integer
alternative list = foldr (\ x y -> if x < 20 then 5*x -3 + y else y) 0 list

AND after try end error i got the solution:

alternative :: [Integer] -> Integer
alternative = foldr (\ x y -> if x < 20 then 5*x -3 + y else y) 0

Solution

  • A list like [1,4,2,5] is syntactical sugar for (:) 1 ((:) 4 ((:) 2 ((:) 5 []))). foldr f z basically replaces the (:) data constructor with f, and the empty list data constructor [] with z. So foldr f z will result in f 1 (f 4 (f 2 (f 5 z))).

    Since you write original [] = 0, this thus means that for z, we can use 0. For f we can use if x < 20 then (+) (5*x-3) else id, since in case x < 20, we add 5*x-3 to the value, and otherwise, we do nothing with the recursively computed value.

    We can thus make an alternative implementation that looks like:

    alternative :: (Foldable  f, Num a, Ord a) => f a -> a
    alternative = foldr f 0
        where f x ys | x < 20 = 5*x - 3 + ys
                     | otherwise = ys

    or without the where clause with an inline lambda expression:

    alternative :: (Foldable  f, Num a, Ord a) => f a -> a
    alternative = foldr (\x -> if x < 20 then (+) (5*x-3) else id) 0