Reputation: 19
I keep getting "error: parse error on input ‘|’ " can someone tell me why? I already rewrote it to make sure all spaces where correct here is my code:
mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
| xs == [] : x
| otherwise = mylast xs
Upvotes: 1
Views: 114
Reputation: 48580
If you really want to avoid writing any patterns, the simplest way is probably foldl'
:
mylast :: [a] -> Maybe a
mylast = foldl' (\_ x -> Just x) Nothing
If you prefer, you can reach down to the primitive catamorphism on lists, foldr
:
mylast :: [a] -> Maybe a
mylast xs = foldr (\x r _ -> r (Just x)) id xs Nothing
but that's a bit trickier to understand.
foldl'
and foldr
are ultimately implemented using pattern matching, because that is the fundamental low-level way to inspect a list in Haskell. So there isn't any way to really avoid it altogether.
Upvotes: 1
Reputation: 152682
The minimal change needed to fix that exact error is just to fix what is probably a typo: you wrote xs == [] : x
, and probably meant xs == [] = x
instead. So:
mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
| xs == [] = x
| otherwise = mylast xs
This will give you a type error, because x
is a list element, and you say mylast
returns a list. You can fix this by making it a singleton list [x]
, as in:
mylast :: (Eq a) => [a] -> [a]
mylast [] = []
mylast (x:xs)
| xs == [] = [x]
| otherwise = mylast xs
From there, I have some stylistic comments.
Maybe
for this role instead of []
; it gives a type-level guarantee of at most one element.Eq a
constraint is unfortunate: it arises because you write xs == []
, which doesn't actually need to call (==)
on any elements, but nevertheless requires the user to provide an implementation of (==)
on elements. The standard way to check if a list is empty is either to call null
or to directly use pattern matching, neither of which require Eq
.Combining these two ideas, we get:
mylast :: [a] -> Maybe a
mylast [] = Nothing
mylast [x] = Just x -- convenient syntax sugar for mylast (x:[]) = Just x
mylast (x:xs) = mylast xs
This looks very idiomatic to me.
Upvotes: 7