Reputation: 6074
I'm experimenting with Haskell and I'm wondering why I couldn't match against a Just containing a pair. I have little experience with this language and I'm completely lost.
f :: Int -> Maybe (Int, [Int])
f 100 = Nothing
f x = Just (x,[x])
g :: Int -> Maybe Int
g x
| u==Nothing = Nothing
| u==(Just (r,s)) = Just r
where
u=f x
So what is wrong with this code. GHC says that r
and s
are not in scope.
Upvotes: 2
Views: 378
Reputation: 105876
If you want to pattern match in a guard, you have to use a pattern guard:
g :: Int -> Maybe Int
g x
| Just (r,_) <- u = Just r
| otherwise = Nothing
where
u = f x
After all, (==)
is a regular function, you need values on both sides to use it. Since r
and s
aren't known in u == Just (r,s)
, the compiler gives you your error message.
By the way, taking a Maybe
and return Nothing
if the value was Nothing
or Just (h x)
for a function h
and Just x
is so common, it forms a pattern: fmap
. You can write
g :: Int -> Maybe Int
g x = fmap fst (f x)
Upvotes: 7
Reputation: 2385
Because the guard expression can't do pattern matching.
Guard expression is just like a boolean expression, it can't do binding. It just uses the binding before |
, in this case x
.
So working solution will be like this.
g :: Int -> Maybe Int
g x = case f x of
Nothing -> Nothing
Just (r,_) -> Just r
Upvotes: 6
Reputation: 12090
You can use case expressions
g :: Int -> Maybe Int
g x =
case f x of
Nothing -> Nothing
Just (r,s) -> Just r
Upvotes: 4