Reputation:
Consider the following data type.
data Movement = Credit Float | Debit Float
deriving Show
And now this function.
retrieveBiggerThan :: [Movement] -> Float -> [Movement]
retrieveBiggerThan l k = (filter (\(Credit c) -> c>k) l) ++ (filter (\(Debit c) -> c>k) l)
If I test this, I receive as output "non-exhaustive patterns in lambda":
retrieveBiggerThan [Credit 5.5, Debit 2.3, Credit 3.3] 2
[Credito 5.5*** Exception: ficha7.hs:116:35-53: Non-exhaustive patterns in lambda
I believe this happens because filter is only expecting for one of the constructors defined in data Movement
. Is there any chance of doing something like this (a filter able to consider both constructors while checking the list)?
filter (\((Credit c) || (Debit c)) -> c > k) listofmovements
Upvotes: 2
Views: 119
Reputation: 38217
you can create a helper called absMovement
and then just trivially filter
using that:
absMovement :: Movement -> Float
absMovement (Credit c) = c
absMovement (Debit d) = d
retrieveBiggerThan k =
filter (\x -> absMovement x > k)
(note the curried definition of the function with also its argument order flipped — this is more idiomatic in Haskell for many practical reasons which are beyond the scope of this post)
you can also go point free(r) if you prefer:
retrieveBiggerThan k =
filter $ (k <) . absMovement
which reads: "retrieving bigger than k [of movements] amounts to filtering [of movements] whose absMovement is greater tham k" — the bracketed phrases correspond to the arguments that were "curried away".
P.S. totally missed that actually using record syntax, you can obtain the absMovement
function for free, as Daniel Wagner points out; but then again it's nice to think of this as abs
ing, in my opinion.
Upvotes: 2
Reputation: 152847
In this specific case, you could use record syntax.
data Movement = Credit { value :: Float } | Debit { value :: Float }
retrieve l k = filter (\mvmt -> value mvmt > k) l
Upvotes: 5
Reputation: 36375
You can use the LambdaCase
extension to make the lambda a bit more concise:
{-# LANGUAGE LambdaCase #-}
data Movement = Credit Float | Debit Float
deriving Show
foo = map (\case { Credit f -> f; Debit d -> d}) [Credit 1, Debit 2]
Upvotes: 5