user4933255
user4933255

Reputation:

Manipulating a value in a Maybe

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

Answers (3)

dfeuer
dfeuer

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

Sam van Herwaarden
Sam van Herwaarden

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 Maybes, it can be very useful in practice.

Upvotes: 1

luqui
luqui

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 Nothings

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

Related Questions