tags:

views:

159

answers:

3

Say I have

x = Just 2

Is there a way (preferrably a builtin mechanism/function) to use x in a single statement such that if it is a Just, then the 2 is automatically unwrapped and used, and if it is a Nothing, an exception is raised?

That is,

(f x) + 2 == 4 if x == Just 2, and raises an exception if x == Nothing.

+6  A: 

fromJust should do what you want.

Tom
+5  A: 

For this particular case, fromJust. In general

let Just k = x in f k + 2 == 4

This trick works with any datatype constructor and is very commonly used with (:) for nonempty lists.

Norman Ramsey
+7  A: 

Data.Maybe.fromJust has been mentioned by other answers already:

fromJust :: Maybe a -> a
fromJust Nothing  = error "Maybe.fromJust: Nothing"
fromJust (Just x) = x

There's also maybe (found in both Prelude and Data.Maybe):

maybe :: b -> (a -> b) -> Maybe a -> b
maybe n _ Nothing  = n
maybe _ f (Just x) = f x

fromJust can be written using maybe:

fromJust = maybe (error "Maybe.fromJust: Nothing") id

As you can see, maybe allows you flexibility in handling both cases without requiring pattern matching:

\x -> maybe 0 (+ 2) x  -- Nothing -> 0, Just 2 -> 4

Similarly, Prelude and Data.Either have either :: (a -> c) -> (b -> c) -> Either a b -> c:

\x -> either (subtract 1) (* 2) x  -- Left 5 -> 4, Right 3 -> 6

If you define a data type

data MyDataType
  = TypeA { foo :: Int, bar :: String }
  | TypeB { foo :: Int,                baz :: () }
  | TypeC {             bar :: String, baz :: () }

like this, you end up with partial functions for accessors.

foo :: MyDataType -> Int
bar :: MyDataType -> String
baz :: MyDataType -> ()

They're called partial functions, as opposed to total functions, because they only return results for a subset of their inputs.

foo (TypeA { foo = 15, bar = "hello!" })  -- 15
bar (TypeB { foo = 12345679, baz = () })  -- error
ephemient