Own implementation of MaybeT lift - haskell

I am trying to implement:
instance MonadTrans MaybeT where
lift m = m >>= \a -> MaybeT $ return (Just a)
And it gets compiler error:
Could not deduce (m ~ MaybeT m)
from the context (Monad m)
bound by the type signature for
lift :: Monad m => m a -> MaybeT m a
at MaybeTrans.hs:16:9-53
`m' is a rigid type variable bound by
the type signature for lift :: Monad m => m a -> MaybeT m a
Expected type: MaybeT m a
Actual type: m a
In the first argument of `(>>=)', namely `m'
In the expression: m >>= \ a -> MaybeT $ return (Just a)
In an equation for `lift':
lift m = m >>= \ a -> MaybeT $ return (Just a)
I cannot understand where I made a mistake.
Please help me ;)

If you specialise the type of lift to your MaybeT type you have:
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
lift :: Monad m => m a -> MaybeT m a
The type of >>= is Monad m => m a -> (a -> m b) -> m b so in your implementation:
lift m = m >>= \a -> MaybeT $ return (Just a)
you need to return a value of type m b while you return a value of type MaybeT m b, hence the error.
You now have two problems. The first is you need to move the application of MaybeT outside the application of >>=. The second is you need to construct a value of m (Maybe a) from the lamba passed to >>= i.e.
lift x = MaybeT $ x >>= \a -> return (Just a)
or simply:
lift x = MaybeT $ fmap Just x

Related

argument of runMaybeT of MaybeT

In https://en.wikibooks.org/wiki/Haskell/Monad_transformers, I see
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
and then the instanciation of MaybeT as a monad:
instance Monad m => Monad (MaybeT m) where
return = MaybeT . return . Just
-- The signature of (>>=), specialized to MaybeT m:
-- (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
x >>= f = MaybeT $ do maybe_value <- runMaybeT x
case maybe_value of
Nothing -> return Nothing
Just value -> runMaybeT $ f value
I do not understand the arg x in runMaybeT x. Shouldn't runMaybeT take an arg corresponding to a? But instead it is given x which is the entire MonadT monad
It's just standard record syntax. In a type definition such as
data Foo = Foo { a :: Int, b :: String }
it presumably does not surprise you that we automatically get functions a :: Foo -> Int and b :: Foo -> String.
It's absolutely no different for MaybeT. (It does use newtype rather than data but that doesn't matter here, the same would be true if the definition used data instead)
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
this gives us a function runMaybeT :: MaybeT m a -> m (Maybe a) for exactly the same reason that we get the functions a and b in the simpler example above. It's just what record syntax does.
Specifically in this case, as always with a newtype defined using record syntax, the runMaybeT function allows us to "unwrap" a monadic value, going from the abstract MaybeT m a to the more "concrete" representation as a value of type m (Maybe a).
This is used in the implementation of >>= for MaybeT m: since its first argument (x in your snippet) is of type MaybeT m a, we first need runMaybeT to get the "unwrapped" value of type m (Maybe a), then use the >>= of the "base monad" m (shown here with do notation) to "extract" a value of type Maybe a which is then pattern matched on in the usual way.
runMaybeT is a getter. It is a function that takes a MaybeT m a object, and returns an m (Maybe a) object, so it has signature MaybeT m a -> m (Maybe a).
Perhaps it is easier to understand however if we unpack the value with a pattern:
instance Monad m => Monad (MaybeT m) where
return = MaybeT . return . Just
MaybeT rm >>= f = MaybeT $ do
maybe_value <- rm
case maybe_value of
Nothing -> return Nothing
Just value -> runMaybeT $ f value

"MonadReader (Foo m) m" results in infinite type from functional dependency

I am trying to pass a function in a Reader that is to be called from the same monad as the calling function, but I get an infinite type error.
The simplified code is:
{-# LANGUAGE FlexibleContexts #-}
module G2 where
import Control.Monad
import Control.Monad.Reader
data Foo m = Foo { bar :: m () }
runFoo :: MonadReader (Foo m) m => m ()
runFoo = do
b <- asks bar
b
main :: Monad m => m ()
main = do
let bar = return () :: m ()
foo = Foo bar
runReaderT runFoo foo
And the error is:
• Occurs check: cannot construct the infinite type:
m0 ~ ReaderT (Foo m0) m
arising from a functional dependency between:
constraint ‘MonadReader
(Foo (ReaderT (Foo m0) m)) (ReaderT (Foo m0) m)’
arising from a use of ‘runFoo’
instance ‘MonadReader r (ReaderT r m1)’ at <no location info>
• In the first argument of ‘runReaderT’, namely ‘runFoo’
In a stmt of a 'do' block: runReaderT runFoo foo
In the expression:
do let bar = ...
foo = Foo bar
runReaderT runFoo foo
• Relevant bindings include main :: m () (bound at G2.hs:16:1)
|
19 | runReaderT runFoo foo
| ^^
Any help would be much appreciated, thanks!
runFoo :: MonadReader (Foo m) m => m ()
Let's forget about the class, and just assume that MonadReader env mon means that mon ~ ((->) env). This corresponds to simply using (->) as our monad instead of the fancier ReaderT. Then you get m ~ ((->) m) => m (). You see that m needs to contain itself (specifically, the argument to m is m). This is OK for values, but it would be quite bad if the typechecker had to deal with infinitely large types. The same is true for ReaderT (and you need to use ReaderT because you call runReaderT runFoo). You need to define another newtype to encode this recursion:
data RecReader c a = RecReader { runRecReader :: c (RecReader c) -> a }
instance Functor (RecReader c) where
fmap f (RecReader r) = RecReader $ f . r
instance Applicative (RecReader c) where
pure = RecReader . const
RecReader f <*> RecReader g = RecReader $ \e -> f e (g e)
instance Monad (RecReader c) where
return = pure
RecReader x >>= f = RecReader $ \e -> runRecReader (f (x e)) e
instance MonadReader (c (RecReader c)) (RecReader c) where
ask = RecReader id
local f (RecReader x) = RecReader $ x . f
And it works:
runRecReader runFoo (Foo $ return ())
-- ==>
()

Haskell. Lifting monad Error and local function

data InterpreterM a = ExeInterpreter a | PropInterpreter a
newtype InterpreterMT m a = InterpreterMT { runInterpreterMT :: m (InterpreterM a) }
type Interpreter = InterpreterMT (StateT Int (ReaderT Int (ErrorT String IO)))
data Stmts = Statements Stmt Stmts | EmptyStmts
instance (Monad m) => Monad (InterpreterMT m) where
return x = InterpreterMT $ return (ExeInterpreter x)
x >>= f = InterpreterMT $ do
m <- runInterpreterMT x
case m of
(ExeInterpreter a) -> runInterpreterMT (f a)
interpreter :: Stmts -> Interpreter ()
interpreter EmptyStmts = return ()
interpreter (Statements s stmts) = lift $ local (\x -> x) (interpreter stmts)
instance MonadTrans InterpreterMT where
lift m = InterpreterMT $ do
x <- m
return $ ExeInterpreter x
Compiler gives me erorr in last line:
Couldn't match type `InterpreterMT
(StateT Int (ReaderT Int (ErrorT String IO)))'
with `StateT Int (ReaderT Int (ErrorT String IO))'
Expected type: Interpreter ()
Actual type: InterpreterMT
(InterpreterMT (StateT Int (ReaderT Int (ErrorT String IO)))) ()
In the expression: lift $ local (\ x -> x) (interpreter stmts)
In an equation for `interpreter':
interpreter (Statements s stmts)
= lift $ local (\ x -> x) (interpreter stmts)
How to repair it and why it is an error?
Okay, two problems.
First, lift has the following signature:
lift :: (MonadTrans t, Monad m) => m a -> t m a
So you have to supply non-transformed monadic action to lift. In other words, you can't use InterpreterMT in an argument to lift.
So you would need to unwrap it:
lift $ local id $ runInterpreterMT $ interpreter stmts
But now your return types don't make sense: runInterpreterMT $ ... has type
StateT Int (ReaderT Int (ErrorT String IO)) (InterpreterM ())
or, shortening transformer stack to M,
M (InterpreterM ())
while interpreter returns Interpreter (), which is
InterpreterMT (StateT Int (ReaderT Int (ErrorT String IO))) ()
or, shortening transformer stack,
InterpreterMT M ()
going back to type of lift, m a -> t m a becomes M (InterpreterM ()) -> InterpreterMT M (InterpreterM ()). (InterpreterM ()) is not ().
The root of the problem? Your InterpreterMT is not actually a monad transformer, since it doesn't really transform the monad. It transforms the value.
Easy fix? Provided that you can figure out a reasonable Monad instance for InterpreterMT (one you provided is doubtful), you can define a MonadReader instance for InterpreterMT:
instance MonadReader r m => MonadReader r (InterpreterMT m) where
local f = InterpreterMT . local f . runInterpreterMT
...
(you'll need UndecideableInstances for this particular definition)
General pattern seems to be
inInterpreter f = InterpreterMT . f . runInterpreterMT
Note that this is not a Functor.
Not sure what you want to achieve here, but this whole design seems... underdeveloped. Maybe it's a good idea to go back to drawing board and figure out what exactly you want your architecture to be like.

Own Monad Transformer and lifting

data InterpreterM a = ExeInterpreter a | PropInterpreter a
newtype InterpreterMT m a = InterpreterMT { runInterpreterMT :: m (InterpreterM a) }
instance (Monad m) => Monad (InterpreterMT m) where
return x = lift . return
x >>= f = InterpreterMT $ do
m <- runInterpreterMT x
case m of
(ExeInterpreter a) -> runInterpreterMT (f a)
instance MonadTrans InterpreterMT where
lift m = lift . (ExeInterpreter m)
I've got error, and I don't know why:
Interpreter.hs:25:20:
Couldn't match expected type `InterpreterMT m a'
with actual type `a2 -> t1 m1 a2'
In the expression: lift . return
In an equation for `return': return x = lift . return
In the instance declaration for `Monad (InterpreterMT m)'
Interpreter.hs:32:18:
Couldn't match expected type `InterpreterMT m a'
with actual type `a0 -> t0 m0 a1'
In the expression: lift . (ExeInterpreter m)
In an equation for `lift': lift m = lift . (ExeInterpreter m)
In the instance declaration for `MonadTrans InterpreterMT'
Interpreter.hs:32:27:
Couldn't match expected type `a0 -> m0 a1'
with actual type `InterpreterM (m a)'
In the return type of a call of `ExeInterpreter'
Probable cause: `ExeInterpreter' is applied to too many arguments
In the second argument of `(.)', namely `(ExeInterpreter m)'
In the expression: lift . (ExeInterpreter m)
What nicolas said. I didn't use the point-free style, so it might be a little bit easier to understand the types. You can look into example implementations to get a better feeling for transformers - Control.Monad.Trans.Class
data InterpreterM a = ExeInterpreter a
| PropInterpreter a
newtype InterpreterMT m a = InterpreterMT { runInterpreterMT :: m (InterpreterM a) }
instance (Monad m) => Monad (InterpreterMT m) where
-- return :: Monad m => a -> InterpreterMT m a
return x = InterpreterMT $ (return . ExeInterpreter) x
-- or after you defined MonadTrans below
-- return x = lift . return $ x
-- (>>=) :: Monad m => InterpreterMT m a -> (a -> InterpreterMT m b) -> InterpreterMT m b
(>>=) ima f = InterpreterMT $ do
ia <- runInterpreterMT ima
case ia of
(ExeInterpreter a) -> runInterpreterMT $ f a
(PropInterpreter a) -> runInterpreterMT $ f a
instance MonadTrans InterpreterMT where
-- lift :: Monad m => m a -> InterpreterMT m a
lift ma = InterpreterMT $ (return . ExeInterpreter) =<< ma
You dont seem to have any instance of MonadTrans in context so lift does not exist.
But more importantly, look at the type of the functions.
x is a value of type a and return x needs to give an element of type (InterpreterMT m) a.
For this you need to use the data constructor InterpreterMT and give it a m (InterpreterM a)
which means the body of return should be like
return . PropInterpreter $ x

How to lift function to transformed monad in haskell?

I know with the data constructor and the run*** function,
I can lift any function to a specific MonadTrans instance.
Like this,
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import Control.Monad
liftF :: (Monad m) => (a -> b) -> MaybeT m a -> MaybeT m b
liftF f x = MaybeT $ do
inner <- runMaybeT x
return $ liftM f inner
But how can I generalize this liftF to
liftF :: (MonadTrans t, Monad m) => (a -> b) -> t m a -> t m b
As #thoferon mentioned, you can just use liftM:
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import Control.Monad (liftM)
liftF :: (Monad m) => (a -> b) -> MaybeT m a -> MaybeT m b
liftF f m = liftM f m
liftF' :: (MonadTrans t, Monad m, Monad (t m)) => (a -> b) -> t m a -> t m b
liftF' f m = liftM f m
(I had to add an additional Monad constraint to liftF').
But why would you do this? Check out the source code for MaybeT -- there's already a Monad instance:
instance (Monad m) => Monad (MaybeT m) where
fail _ = MaybeT (return Nothing)
return = lift . return
x >>= f = MaybeT $ do
v <- runMaybeT x
case v of
Nothing -> return Nothing
Just y -> runMaybeT (f y)
And actually, as liftM is the same as Functor's fmap:
instance (Functor m) => Functor (MaybeT m) where
fmap f = mapMaybeT (fmap (fmap f))
You can find similar instances for all the transformers.
Is this what you are asking? Can you provide some more concrete examples that show what you're trying to do and why, and in what way the existing Functor and Monad instances fail to meet your needs?

Resources