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
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
).
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.