Haskell beginner here again. If I want to unwrap a Maybe
type and want to keep it abstract I would use:
fUnwrap :: Maybe a -> a
fUnwrap (Just n) = n
fUnwrap Nothing = ???
No matter what I do with Nothing
, compiler keeps nagging about being more specific on what to do with Nothing
... Can you guys help me out?
That is logical. The compiler explects a value of type a
, but here there is no value you can provide, since a
can be anything (a Bool
, Int
, [Int]
, Maybe Int
, etc.).
This is not that much a programming problem, it is more a design problem: what do you want to do in case it is a Nothing
? There are some options here:
providing a default value, so then the signature is:
fUnwrap :: a -> Maybe a -> a
fUnwrap _ (Just n) = n
fUnwrap d Nothing = d
we raise an error in case it is Nothing
(we can do this both be leaving the line out, or raising an error explicitly, although in the latter case we can specify a reason):
fUnwrap :: Maybe a -> a
fUnwrap (Just n) = n
fUnwrap Nothing = error "Nothing has no value"
we return undefined
:
fUnwrap :: Maybe a -> a
fUnwrap (Just n) = n
fUnwrap Nothing = undefined
undefined :: a
is an object that raises an error if it is evaluated. It is thus a special case of error
, but we "postpone" evaluation such that if the value is not necessary, we do not get an error.
But personally I think the first approach is advisable here, since function signatures do not specify that these can raise an error, it thus results in code that might fail, without having a hint that it can.
A Maybe a
is typically used as the result type of a computation that can "fail": in case it succeeds, it returns Just x
(with x
the result), and otherwise it returns Nothing
.
You can use for example do
notation to construct a Maybe a
out of a chain of computations that can fail. For example:
foo :: Int -> Maybe Int
foo x = do
y <- someComputation x
otherComputation y
with here fore example someComputation, otherComputation :: Int -> Maybe Int
.