I'm learning Haskell. This is a trivial example but I'd like to understand the concept why I can't use the pattern matching inside the lambda function in the following example (ie, why does the filterfold' function run but filterfold' gives a runtime error):
-- Runs
filterfold' :: (a -> Bool) -> [a] -> [a]
filterfold' p zs = foldr (\y zs -> if (p y) then y:zs else zs) [] zs
-- Runtime error: Non-exhaustive patterns in lambda
filterfold :: (a -> Bool) -> [a] -> [a]
filterfold p (z:zs) = foldr (\y (z:zs) -> if (p y) then y:(z:zs) else (z:zs)) [] (z:zs)
you can use it but as the compiler tells you you are missing a case (when the input is []
)
See if you say z:zs
it will try to match this pattern with the input-list - if you
[1,2,3] = 1:[2,3]
you get z=1
and zs=[2,3]
[]
you cannot get a z
and zs
so that z:zs = []
(technically they are based on different constructors of the list-datatype) So at runtime it will not know how to handle this case/pattern when it sees []
and throw the exception.
if you look closely at your example you should see that you never actually use the parts anyway (meaning z
or zs
- you only use them as z:zs
again) so I cannot tell you how to do it better
anyway you can use the case
- expression inside of an lambda:
... = foldr (\ x zs -> case zs of
[] -> ...
z:zs -> ...
or you can use the LambdaCase extension to make it a bit shorter.
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.