Reputation: 3083
Is it possible to have guards on lambda functions?
For example:
\k
| k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
Upvotes: 55
Views: 25175
Reputation: 29110
Other answers show how the extensions LambdaCase
and MultiWayIf
, introduced since this answer was first written, can solve this. Without them, the nearest direct translation is something a bit like
\k -> case () of
_ | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
Upvotes: 62
Reputation: 1176
Yet another way uses a combination of the LambdaCase
and ViewPatterns
GHC extensions:
{-# LANGUAGE LambdaCase, ViewPatterns #-}
\case
((< 0) -> True) -> "negative"
((==0) -> True) -> "zero"
_ -> "positive"
This keeps you from having to name an intermediate variable.
Upvotes: 2
Reputation: 4993
An elegant and concise way to do it with LambdaCase:
{-# LANGUAGE LambdaCase #-}
\case k | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
or
\case
k | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
A case when I used it, to catch an EOF error:
{-# LANGUAGE ScopedTypeVariables #-}
o <- hGetContents e `catch` (\case (e :: IOException) | isEOFError e -> return "")
Upvotes: 8
Reputation: 55049
As of GHC 7.6.1 there is an extension called MultiWayIf
that lets you write the following:
\k -> if
| k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
Which at the very least is more pleasant to look at than the alternative using case
.
For pattern-matching, there is a related extension called LambdaCase
:
\case
"negative" -> -1
"zero" -> 0
"positive" -> 1
_ -> error "invalid sign"
These extensions are not part of standard Haskell, though, and need to be enabled explicitly via a {-# LANGUAGE LambdaCase #-}
or {-# LANGUAGE MultiWayIf #-}
pragma at the top of the file, or by compiling with the flag -XLambdaCase
or -XMultiWayIf
.
Upvotes: 53
Reputation: 139621
I like to keep lambdas short and sweet so as not to break the reader's visual flow. For a function whose definition is syntactically bulky enough to warrant guards, why not stick it in a where
clause?
showSign k = mysign ++ " (" ++ show k ++ ")"
where
mysign
| k < 0 = "negative"
| k == 0 = "zero"
| otherwise = "positive"
Upvotes: 30