How to inject a Maybe value into MaybeT - haskell

Say I have some foo :: Maybe Int and I want to bind it for example with bar :: Int -> MaybeT (Writer String) Int, what would be the idiomatic way to do that?
I could define my own liftMaybe function, and then use that, like:
let liftMaybe = maybe (fail "Nothing") return in liftMaybe foo >>= bar
But is there a more idiomatic (or at least concise) way to do that?

MaybeT . return :: (Monad m) => Maybe a -> MaybeT m a
I think it's a shame it doesn't have a standard name, however doing a hoogle search, we see that the relude packages uses hoistMaybe:
hoistMaybe :: Applicative m => Maybe a -> MaybeT m a
A more general form is
liftMaybe :: (MonadPlus m) => Maybe a -> m a
liftMaybe = maybe mzero return
which is preferable to the use of fail. I'd just put it in a convenient module somewhere.

Related

How to declare that the composition of two types is a monad

I have function:
step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
When I use do notation in the body of the function, it uses m as the monad. As you might expect, I actually want it to be using m Maybe. But, it doesn't understand that m Maybe is a monad. How do I express that to Haskell?
EDIT: This may be slightly malformed at the moment. The concrete type should be
StateT IntCodeState Maybe (), but I'm trying not to declare the concrete type, so the question is: how do I declare that?
EDIT 2: Another attempt: I've got some functions that look like this:
getValueIndex :: (MonadState IntCodeState m) => Int -> m (Maybe Int)
Here, I'm working on the level of the state monad. However, I now want to be able to act "as if" m Maybe was the monad. I was hoping this was simple but I can't figure out a way of expressing it. The code I want to write looks like this
step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
step = do
full <- opCode
let len = length (snd full) + 1
process full <* (next += len)
But opCode returns a m (Maybe a) and I want full to be an a
But opCode returns a m (Maybe a) and I want full to be an a
Looks like you want to use the MaybeT monad transformer, which is m (Maybe a) under the hood, with its Monad instance doing what you need:
The MaybeT monad transformer extends a monad with the ability to exit the computation without returning a value.
A sequence of actions produces a value only if all the actions in the sequence do. If one exits, the rest of the sequence is skipped and the composite action exits.
Here are the types:
MaybeT :: m (Maybe a) -> MaybeT m a
runMaybeT :: MaybeT m a -> m (Maybe a)
This will also be helpful, specialised from MonadTrans:
lift :: m a -> MaybeT m a
So in your case:
step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
step = runMaybeT $ do
full <- MaybeT opCode -- :: MaybeT opCode :: MaybeT m a, full :: a
let len = length (snd full) + 1
lift $ process full <* (next += len)
I've assumed process returns an m () and used lift to change it into MaybeT m ().

Apply a function to a value inside IO Maybe

I have a function of type a -> IO (Maybe b) and I want to apply it to IO (Maybe a) and get IO (Maybe b). I wrote a function to do that:
ioMaybeApply :: (a -> IO (Maybe b)) -> IO (Maybe a) -> IO (Maybe b)
ioMaybeApply f ioMaybeA = do
maybeA <- ioMaybeA
maybe (return Nothing) f maybeA
Is there a standard Haskell function to do that? I tried searching with Hoogle but I didn't find anything. If not, is my implementation good, or could it be simpler?
This can be achieved through the MaybeT monad transformer:
GHCi> import Control.Monad.Trans.Maybe
GHCi> :t \f m -> runMaybeT (MaybeT m >>= MaybeT . f)
\f m -> runMaybeT (MaybeT m >>= MaybeT . f)
:: Monad m => (a1 -> m (Maybe a)) -> m (Maybe a1) -> m (Maybe a)
import Control.Monad.Trans.Maybe
-- Making it look like your definition, for the sake of comparison.
ioMaybeApply :: (a -> IO (Maybe b)) -> IO (Maybe a) -> IO (Maybe b)
ioMaybeApply f ioMaybeA = runMaybeT $ do
a <- MaybeT ioMaybeA
MaybeT (f a)
If you are using this pattern in multiple places, it will likely pay off to change your a -> IO (Maybe b) functions to a -> MaybeT IO b -- then you can just use (>>=) and/or seamless do-blocks instead of your special-purpose function. On the other hand, if this is just an one-off you may reasonably think that using MaybeT would be overkill; in that case, your implementation is perfectly fine.
(It is worth mentioning that while there is a general-purpose wrapper for nested functors called Compose that has Functor and Applicative instances, it doesn't have a Monad instance, as nesting two monads doesn't necessarily result in something that can be given a legal Monad instance. That being so, we typically resort to monad transformers tailored for each combination that works.)

a generic monadic `(<|>)`?

I'm looking for a more concise / idiomatic way of writing getAorB:
getAorB = do
a <- getA
case a of
Just _ -> return a
Nothing -> getB
Does this already exist as a library function somewhere?
Note that liftM2 (<|>) getA getB is the same as:
do a <- getA
b <- getB
return $ a <|> b
which is different from getAorB since bind is always called on getB even if getA returns a Just.
You can use the maybe function (b -> (a -> b) -> Maybe a -> b) with its default value:
getAorB :: Monad m => m a
getAorB = getA >>= maybe getB return
I don't think there's a single function that does this anywhere.
Trying to use an Alternative (such as MaybeT) doesn't work well here imo as it considers the second action to be fallible as well, which your getB isn't. If it if was, you should consider using MaybeT though:
getAorB :: Monad m => m (Maybe a)
getAorB = runMaybeT $ MaybeT getA <|> MaybeT getB
Sounds like an mplus for MaybeT.
Since (<|>) gets it's powers from applicative isn't this impossible?
It feels like the type you are looking for is something like
Monad m => a ->[m (Maybe a)] -> m a
instead? Or maybe
Monad m => a -> (a -> Bool) -> [m a] -> m a
Hoogle doesn't give me anything for either.
To hide all the transformers:
import Control.Monad.Trans.Maybe
getAOrB :: m (Maybe a) -> m (Maybe a) -> m (Maybe a)
getAOrB getA getB = runMaybeT (MaybeT getA <|> MaybeT getB)
But I would probably just use MaybeT everywhere instead:
getAOrB' :: MaybeT m a -> MaybeT m a -> MaybeT m a
getAOrB' = (<|>)
Note that this type is slightly different than the type of your first implementation; it has the same type as your second implementation but better behavior.

How do I solve this monadT relationship in Haskell?

I met this question today while learning haskell monad transformers.
Assume I have a type instance Monad m => Monad (CustomT m).
If there's a function f :: CustomT IO Int, and there's g :: IO (Maybe Int).
How do I access the Int of g in f?
I tried something like
f = do
mVal <- g
This didn't work because f is under CustomT IO monad while g is under MaybeT IO monad.
And then I tried
f = do
mVal <- return g
This seems to work but mVal is IO (Maybe Int) type, I eventually get nested IO like CustomT IO (IO something)
Is there a way to get that Int or Maybe Int out in f?
What knowledge is involved?
Thanks in advance.
In the general case, Jeremy's answer is what you want. But let's see if we can work with your specific case here. We have f :: CustomT IO Int and g :: IO (Maybe Int), given that there exist some instances to the effect of instance Monad m => Monad (CustomT m) and instance MonadTrans CustomT.
And what you want is to get at the Int inside of a g within the context of CustomT IO. Since we're inside of CustomT, we can basically strip that layer off trivially. Like Jeremy says, use lift to get rid of that.
lift :: (MonadTrans t, Monad m) => m a -> t m a
So now we have CustomT IO (Maybe Int). Like I said, we're inside a do-block, so using Haskell's bind (<-) syntax gets rid of the monad layer temporarily. Thus, we're dealing with Maybe Int. To get from Maybe Int to Int, the usual approach is to use maybe
maybe :: b -> (a -> b) -> Maybe a -> b
This provides a default value just in case the Maybe Int is actually Nothing. So, for instance, maybe 0 id is a function that takes a Maybe Int and yields the inner Int, or 0 if the value is Nothing. So, in the end, we have:
f = do
mVal <- maybe 0 id $ lift g
-- Other code
In the Control.Monad.Trans you have this definition for monad transformers:
class MonadTrans (t :: (* -> *) -> * -> *) where
lift :: Monad m => m a -> t m a
Which means that if CustomT has been defined properly you can do this:
f = do
mVal <- lift g

How does Haskell infer correct type classes in MaybeT implementation?

How does Haskell know which is correct monad instance for each return expression?
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance Monad m => Monad (MaybeT m) where
return = MaybeT . return . return
It's actually unambiguous from the context.
Let's play the typechecker,
-- From the signature
MaybeT . return . return :: a -> MaybeT a
-- From the type of MaybeT
return . return :: a -> m (Maybe a)
-- From the type of `.`
(return :: Maybe a -> m a) . (return :: a -> Maybe a)
And once we have the type of each return, the "instance selection algorithm" will correctly choose the first to use ms return and the second to be Maybe.
It infers the needed types.
It's clear from the meaning of an instance definition that we're trying to define
returnMaybeT :: Monad m => a -> MaybeT m a
returnMaybeT x = MaybeT (return (return x))
Since MaybeT :: m (Maybe a) -> MaybeT a (taken as a function) we know that the inner stack of returns must have type
return (return x) :: Monad m => a -> m (Maybe a)
Now, we know that return is a polymorphic function which has a type like
return :: a -> n a
for any Monad n. In the case of this first return, the Monad m => constraint tells us that m is a Monad and so we can use its definition of return. This lets us get all the way down to the inner return
return x :: a -> Maybe a
and since we know that Maybe has a Monad instance we can use the return from that.
Ultimately, all the compiler has to do is whittle its way down the expression trying to determine the types needed at each return. After it determines the needed type it has to check to see if it knows a Monad instance for that type. This is simple for Maybe, since it's concrete, but a little more difficult to see for m since it's just a variable.
The reason m works is because we've constrained the variable to certainly be some type which instantiates Monad.

Resources