简体   繁体   中英

Pattern matching inside lambda

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

  • input [1,2,3] = 1:[2,3] you get z=1 and zs=[2,3]
  • but when input [] 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM