Looking at the MaybeT
transformer:
ghci> let x = MaybeT $ Just 1234
ghci> let y = runMaybeT x
ghci> :t y
y :: Num (Maybe a) => Maybe (Maybe a)
Now I want to get the inner Maybe a
, but join
does not work.
ghci> join y
<interactive>:53:1:
No instance for (Num (Maybe a0)) arising from a use of `it'
In a stmt of an interactive GHCi command: print it
How can I get at the inner Maybe a
value?
You are not using the MaybeT
constructor correctly. Look at the type signatures:
MaybeT :: m (Maybe a) -> MaybeT m a
| | |
/-+-\ \---+---/
| | |
Just 1234 :: Num x => Maybe x
Hence:
m := Maybe
x := Maybe a
Therefore:
MaybeT $ Just 1234 :: Num (Maybe a) => MaybeT Maybe a
So here Maybe a
is expected to be an instance of Num
which is clearly wrong. An option type is not a number. Why does this problem arise?
Consider the numeric literal 1234
. Numeric literals are bounded polymorphic values in Haskell. Hence, they have the type Num x => x
. In other words 1234
can be of any type depending upon the context as long as that type is an instance of Num
(e.g. Int
, Integer
, Double
).
In your code, the polymorphic type x
is instantiated to Maybe a
which is why Haskell expects Maybe a
to be an instance of Num
.
I think what you really want to do is this:
MaybeT :: m (Maybe a) -> MaybeT m a
return $ Just 1234 :: (Num a, Monad m) => m (Maybe a)
Therefore:
MaybeT $ return $ Just 1234 :: (Num a, Monad m) => MaybeT m a
Now you can easily extract the inner Maybe a
:
runMaybeT $ MaybeT $ return $ Just 1234 :: (Num a, Monad m) => m (Maybe a)
Since the inner Maybe a
value is wrapped in a monad all you need to do is use >>=
to extract the Maybe a
:
(runMaybeT $ MaybeT $ return $ Just 1234) >>= \x -> do
-- do something with x
-- x :: Maybe a
You could also write this using the do
notation:
do
x <- runMaybeT $ MaybeT $ return $ Just 1234
-- do something with x
-- x :: Maybe a
Hope that helps.