Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

length of list using foldr in haskell

Tags:

haskell

I wrote the following code to calculate length of a list using foldr in haskell. When I compile the code it gives me error as "myfoldr.hs:3:1: parse error on input `where'". Can anyone please tell me what thing I might be missing or doing wrong in this code ?

mylength :: [Int] -> Int
mylength l = foldr f 0 l
where
f :: Int -> Int -> Int
f x y = y+1
like image 862
Sushodhan Avatar asked Dec 05 '25 04:12

Sushodhan


2 Answers

In Haskell, whitespace matters - look at the guide on the Haskell wiki.

Formatting your code more correctly gives:

mylength :: [Int] -> Int
mylength l = foldr f 0 l
  where
    f :: Int -> Int -> Int
    f x y = y + 1

Which works perfectly (although the argument x to f is a bit redundant, you might want to write it as f _ y = y + 1 instead, or use a lambda expression like foldr (\_ x -> x + 1) 0 l).

like image 165
hnefatl Avatar answered Dec 07 '25 19:12

hnefatl


This is an indentation error: you have to indent the where clause, since otherwise Haskell will see the definition of f as a separate function. So we can fix it with:

mylength :: [Int] -> Int
mylength l = foldr f 0 l
    where f :: Int -> Int -> Int
          f x y = y+1

Nevertheless we can still make it more generic: instead of defining it for an [Int] list, we can define it over an [a] list, with:

mylength :: [a] -> Int
mylength l = foldr f 0 l
    where f x y = y+1

We can also rewrite f as const (+1), so:

mylength :: Num n => [a] -> n
mylength = foldr (const (1+)) 0

Note that we can apply an eta-reduction here: remove l both in the head and the body of the mylength definition. Or in case we know that the number is also enumerable, we can use succ instead of (1+):

mylength :: (Enum n, Num n) => [a] -> n
mylength = foldr (const succ) 0
like image 28
Willem Van Onsem Avatar answered Dec 07 '25 19:12

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!