Reputation:
A function in some code I'm writing returns
Just 3
What I'd like is to remove the Just and manipulate 3 as I please.
I must confess to not understanding the Just syntax, but while I work that out, I'd appreciate some help with this.
Upvotes: 0
Views: 129
Reputation: 48611
If I give you a recipe for chocolate cake, you can't take off the recipe and just eat the cake as you see fit. You first have to follow the recipe.
Similarly, if I give you a Maybe Int
, you can't just take off the Maybe
and manipulate the Int
; you must first inspect it to see whether you got Just
an Int
you can manipulate or Nothing
.
The most fundamental way to perform this inspection, which all other techniques use, is pattern matching. The fromMaybe
function luqui suggests will serve as a good example. It turns a Maybe a
into an a
, using the given default if it finds Nothing
.
fromMaybe :: a -> Maybe a -> a
fromMaybe def (Just val) = val
fromMaybe def Nothing = def
Pro tip: as you go through the process of learning Haskell, you will find several good opportunities to think back on the parable of the cake.
Upvotes: 3
Reputation: 2361
Another function that might be useful, and which is actually in the Prelude
, is
maybe :: b -> (a -> b) -> Maybe a -> b
which is very similar to fromMaybe
but lets you use a function to work on the variable inside your Just
instead (you need to give a default that matches the type of the output of the function for if you have Nothing
). Example:
maybeShow = maybe "Got nothing..." show
maybeShow $ Just 3 -- gives "3"
maybeShow $ Nothing -- gives "Got nothing..."
And then there is a function which the other answerers seem to have strategically avoided :) But I think it should be here for completeness:
import Data.Maybe (fromJust)
fromJust :: Maybe a -> a
which takes a value out of its Just
wrapper. The problem with this function is it's a partial function, i.e. it's not defined for Nothing
values:
fromJust $ Just 3 -- gives 3
fromJust $ Nothing -- gives *** Exception: Maybe.fromJust: Nothing
so as you can see this function is kind of risky to use and it's definitely not a clean solution. Still, if you're sure you will not get Nothing
, or if you're just playing around and you want to get rid of annoying Maybe
s, it can be very useful in practice.
Upvotes: 1
Reputation: 60503
Just 3
has type Maybe Int
. You can either manipulate the int within the Maybe
, the simplest form of that being fmap
, e.g.
ghci> fmap (\x -> x + 1) (Just 3)
Just 4
which preserves the structure of the Maybe
type, that is to say, it preserves Nothing
s
ghci> fmap (\x -> x + 1) Nothing
Nothing
Or you can define a function which pattern matches:
doThing :: Maybe Int -> String
doThing (Just x) = "I got " ++ show x
doThing Nothing = "I didn't get anything"
ghci> doThing (Just 3)
"I got 3"
There is also a useful function called fromMaybe
(defined in Data.Maybe
):
fromMaybe :: a -> Maybe a -> a
It will extract the value from a Maybe
, but you have to provide it with what to return if it turned out to be Nothing
:
ghci> import Data.Maybe (fromMaybe)
ghci> fromMaybe 0 (Just 3)
3
ghci> fromMaybe 0 Nothing
0
Note that in all of these cases, we have to decide what to do if the value is Nothing
, which is the essential feature of the Maybe
type.
Upvotes: 7