I have been wondering why Monad Transformers has for example m(Maybe(m(Maybe a)) structural order and why not Maybe(m(Maybe( m a))). I have tried to implement the second one but I'm unable to complete it possibly BCS of my inadequate Haskell knowledge.
In all monad transformers, do we always have a structure like this?
if yes then why?
if not then when to choose one from another?
newtype MaybeOT m a = MaybeOT {runMaybeOT :: Maybe (m a) }
instance (Monad m) => Monad (MaybeOT m) where
return = pure
(MaybeOT mma) >>= f = MaybeOT $
case mma of
Nothing -> Nothing
(Just ma) -> inner ma where
inner ma = do
a <- ma
undefined
You've essentially discovered why monad transformers are inwards instead of outwards (nit: I'm pretty sure I'm not using correct terminology here, but you get what I mean - feel free to correct me here). It's much easier (easy == less constraints) to have the monad you know about be in the data position (inside), rather than the container position (outside). Intuitively, you can see why - after all, the monadic nature demands the container to be the same. You can do whatever you want with the data, but you must not change the type of the container during binding.
Of course, it's easier to realize all this by actually trying to implement the absurd. Which is what this is about. The final step you'll be stuck on while implementing >>=/bind for MaybeOT is this-
m a >>= ??? . runMaybeOT . f
Where, m is a Monad, m a :: m a, f :: a -> MaybeOT m a, and runMaybeOT :: MaybeOT m a -> Maybe (m a) (and also ??? :: ???, hehe)
Now, you must obtain a monad with the container type m to successfully bind on m a. But alas, you cannot get the m a out of Maybe (m a)! What happens when it's Nothing? Your primary tool in implementing monad transformers is knowledge about the specific monad you're implementing the transformer for. And your knowledge is telling you that this is absurd.
In contrast, the final step in implementing >>= for MaybeT goes well smoothly. For completeness, here's MaybeT-
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
Here, you'll be binding on the type m (Maybe a). During binding, you must return the type m b, for whatever b. You're given a function, f, of type a -> MaybeT m b, you can easily get m (Maybe b) from MaybeT m b.
Aha! Now you can see the solution. The function you're given returns the same outer monad as the one you're binding on. That is precisely what you need. In the case of MaybeOT, you were stuck with binding on the monad m, with a function that doesn't return a value with outer monad m!
And that is the crucial realization - the function you're given must be able to give you a value with the same outer monad. This is why MaybeT (and other transformers too) keeps the unknown monad outwards - because when you implement >>= for MaybeT, you know the binding function will be required to construct that outer monad.
It is helpful, at least intuitively, to note that the problem you get stuck on here - is the very same problem you'll face when implementing monadic composition. That is, >>= for nested monads. Monads don't compose! That's why you need monad transformers!
If you break this problem down, you'll notice that if you just had a function that could swap monads, to get Maybe (m a) from m (Maybe a) and vice versa - all would be well. Monads would compose, monad transformers could look like however you please, and in fact, monad transformers would essentially serve no purpose. This detail is noticed in the answer linked above. All you need is-
swap :: (Monad m, Monad n) => m (n a) -> n (m a)
This exists. They're called traversable monads, and indeed if you merely add the Traversable constraint to your Monad implementation for MaybeOT, you strike gold-
instance (Traversable m, Monad m) => Monad (MaybeOT m) where
return = pure
MaybeOT Nothing >>= _ = MaybeOT Nothing
MaybeOT (Just ma) >>= f = MaybeOT $ sequence $ ma >>= sequence . runMaybeOT . f
I assume it's law-conforming, though I'd have to check.
In another note, it is totally possible to make MaybeOT a law conforming applicative. After all, the problem you face while implementing Monad is simply non existent here. Applicatives do compose.
instance Applicative f => Applicative (MaybeT f) where
pure = MaybeT . pure . Just
MaybeT f <*> MaybeT a = MaybeT $ liftA2 (<*>) f a
(Or, perhaps more simply)
instance Applicative f => Applicative (MaybeT f) where
pure = MaybeT . pure . Just
MaybeT f <*> MaybeT a = MaybeT $ (<*>) <$> f <*> a
Which should be law conforming, as far as I can tell.
Related
There have been a couple of questions (e.g. this and this) asking whether every monad in Haskell (other than IO) has a corresponding monad transformer. Now I would like to ask a complementary question. Does every monad have exactly one transformer (or none as in the case of IO) or can it have more than one transformer?
A counterexample would be two monad transformers that would produce monads behaving identically when applied to the identity monad would but would produce differently behaving monads when applied to some other monad. If the answer is that a monad can have more than one transformer I would like to have a Haskell example which is as simple as possible. These don't have to be actually useful transformers (though that would be interesting).
Some of the answers in the linked question seemed to suggest that a monad could have more than one transformer. However, I don't know much category theory beyond the basic definition of a category so I wasn't sure whether they are an answer to this question.
Here's one idea for a counterexample to uniqueness. We know that in general, monads don't compose... but we also know that if there's an appropriate swap operation, you can compose them[1]! Let's make a class for monads that can swap with themselves.
-- | laws (from [1]):
-- swap . fmap (fmap f) = fmap (fmap f) . swap
-- swap . pure = fmap pure
-- swap . fmap pure = pure
-- fmap join . swap . fmap (join . fmap swap) = join . fmap swap . fmap join . swap
class Monad m => Swap m where
swap :: m (m a) -> m (m a)
instance Swap Identity where swap = id
instance Swap Maybe where
swap Nothing = Just Nothing
swap (Just Nothing) = Nothing
swap (Just (Just x)) = Just (Just x)
Then we can build a monad transformer that composes a monad with itself, like so:
newtype Twice m a = Twice (m (m a))
Hopefully it should be obvious what pure and (<$>) do. Rather than defining (>>=), I'll define join, as I think it's a bit more obvious what's going on; (>>=) can be derived from it.
instance Swap m => Monad (Twice m) where
join = id
. Twice -- rewrap newtype
. fmap join . join . fmap swap -- from [1]
. runTwice . fmap runTwice -- unwrap newtype
instance MonadTrans Twice where lift = Twice . pure
I haven't checked that lift obeys the MonadTrans laws for all Swap instances, but I did check them for Identity and Maybe.
Now, we have
IdentityT Identity ~= Identity ~= Twice Identity
IdentityT Maybe ~= Maybe !~= Twice Maybe
which shows that IdentityT is not a unique monad transformer for producing Identity.
[1] Composing monads by Mark P. Jones and Luc Duponcheel
The identity monad has at least two monad transformers: the identity monad transformer and the codensity monad transformer.
newtype IdentityT m a = IdentityT (m a)
newtype Codensity m a = Codensity (forall r. (a -> m r) -> m r)
Indeed, considering Codensity Identity, forall r. (a -> r) -> r is isomorphic to a.
These monad transformers are quite different. One example is that "bracket" can be defined as a monadic action in Codensity:
bracket :: Monad m => m () -> m () -> Codensity m ()
bracket before after = Codensity (\k -> before *> k () *> after)
whereas transposing that signature to IdentityT doesn't make much sense
bracket :: Monad m => m () -> m () -> IdentityT m () -- cannot implement the same functionality
Other examples can be found similarly from variants of the continuation/codensity monad, though I don't see a general scheme yet.
The state monad corresponds to the state monad transformer and to the composition of Codensity and ReaderT:
newtype StateT s m a = StateT (s -> m (s, a))
newtype CStateT s m a = CStateT (Codensity (ReaderT s m) a)
The list monad corresponds to at least three monad transformers, not including the wrong one:
newtype ListT m a = ListT (m (Maybe (a, ListT m a))) -- list-t
newtype LogicT m a = LogicT (forall r. (a -> m r -> m r) -> m r -> m r) -- logict
newtype MContT m a = MContT (forall r. Monoid r => (a -> m r) -> m r))
The first two can be found respectively in the packages list-t (also in an equivalent form in pipes),
and logict.
There is another example of a monad that has two inequivalent transformers: the "selection" monad.
type Sel r a = (a -> r) -> a
The monad is not well known but there are papers that mention it. Here is a package that refers to some papers:
https://hackage.haskell.org/package/transformers-0.6.0.4/docs/Control-Monad-Trans-Select.html
That package implements one transformer:
type SelT r m a = (a -> m r) -> m a
But there exists a second transformer:
type Sel2T r m a = (m a -> r ) -> m a
Proving laws for this transformer is more difficult but I have done it.
An advantage of the second transformer is that it is covariant in m, so the hoist function can be defined:
hoist :: (m a -> n a) -> Sel2T r m a -> Sel2T r n a
The second transformer is "fully featured", has all lifts and "hoist". The first transformer is not fully featured; for example, you cannot define blift :: Sel r a -> SelT r m a. In other words, you cannot embed monadic computations from Sel into SelT, just like you can't do that with the Continuation monad and the Codensity monad.
But with the Sel2T transformer, all lifts exist and you can embed Sel computations into Sel2T.
This example shows a monad with two transformers without using the Codensity construction in any way.
By the title, I mean types like Monad m => m (m a).
When the structure of a monad is simple, I can easily think of a usage of such type:
[[a]], which is a multidimensional list
Maybe (Maybe a), which is a type adjoined by two error states
Either e (Either e a), which is like above, but with messages
Monoid m => (m,(m,a)), which is a writer monad with two things to write over
r -> r -> a, which is a reader monad with two things to read from
Identity (Identity a), which is still the identity monad
Complex (Complex a), which is a 2-by-2 matrix
But it goes haywire in my mind if I think about the following types:
ReadP (ReadP a)? Why would it be useful when ReadP isn't an instance of Read?
ReadPrec (ReadPrec a)? Like above?
Monad m => Kleisli m a (Kleisli m a b)?
IO (IO a)!? This must be useful. It just is too hard to think about it.
forall s. ST s (ST s a)!? This should be like the above.
Is there a practical use for such types? Especially for the IO one?
On the second thought, I might need to randomly pick an IO action. That's an example of IO (IO a) which focuses on inputs. What about one focusing on outputs?
In some sense, a monad can be thought of as a functor in which layers can be collapsed.
If the Monad class were defined more like the category-theory definition, it would look like
class Applicative m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
Using fmap with a function of type a -> m b results in a function of type m a -> m (m b). join is used to eliminate one layer of monad from the result. Since that's a common thing to do, one might define a function that does it.
foo :: Monad m => (a -> m b) -> m a -> m b
foo f ma = join (fmap f ma)
If you look carefully, you'll recognize foo as >>= with its arguments flipped.
foo = flip (>>=)
Since >>= is used more than join would be, the typeclass definition is
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
and join is defined as a separate function
join :: Monad m => m (m a) -> m a
join mma = mma >>= id
Does not matter.
Monads are monads precisely because for every Monad ( Monad a ) we can always get Monad a. Such operation is called "join" and it's alternative operation to "bind" that could form definition of Monad. Haskell uses "bind" because its much more useful for composing monadic code :)
(join can be implemented with bind, and bind with join - they are equivalent)
Does not matter
Is actually small lie, since ability to form Monad ( Monad a ) is also de facto part of what makes Monads monads. With Monad (Monad a) being transitional representation in some operations.
Full answer is: Yes, because that enables Monads. Though Monad ( Monad a ) can have extra "domain" meaning as you list for some of the Monads ;)
Is there a way to implement bind for nested monads? What I want is the following signature:
(>>>=) :: (Monad m, Monad n) => m (n a) -> (a -> m (n b)) -> m (n b)
It looks like it should be a trivial task, but I somehow just can't wrap my head around it. In my program, I use this pattern for several different combinations of monads and for each combination, I can implement it. But for the general case, I just don't understand it.
Edit: It seems that it is not possible in the general case. But it is certainly possible in some special cases. E.g. if the inner Monad is a Maybe. Since it IS possible for all the Monads I want to use, having additional constraints seems fine for me. So I change the question a bit:
What additional constraints do I need on n such that the following is possible?
(>>>=) :: (Monad m, Monad n, ?? n) => m (n a) -> (a -> m (n b)) -> m (n b)
Expanding on the comments: As the linked questions show, it is necessary to have some function n (m a) -> m (n a) to even have a chance to make the composition a monad.
If your inner monad is a Traversable, then sequence provides such a function, and the following will have the right type:
(>>>=) :: (Monad m, Monad n, Traversable n) => m (n a) -> (a -> m (n b)) -> m (n b)
m >>>= k = do
a <- m
b <- sequence (fmap k a)
return (join b)
Several well-known transformers are in fact simple newtype wrappers over something equivalent to this (although mostly defining things with pattern matching instead of literally using the inner monads' Monad and Traversable instances):
MaybeT based on Maybe
ExceptT based on Either
WriterT based on (,) ((,) doesn't normally have its Monad instance defined, and WriterT is using the wrong tuple order to make use of it if it had - but in spirit it could have).
ListT based on []. Oh, whoops...
The last one is in fact notorious for not being a monad unless the lifted monad is "commutative" - otherwise, expressions that should be equal by the monad laws can give different order of effects. My hunch is that this comes essentially from lists being able to contain more than one value, unlike the other, reliably working examples.
So, although the above definition will be correctly typed, it can still break the monad laws.
Also as an afterthought, one other transformer is such a nested monad, but in a completely different way: ReaderT, based on using (->) as the outer monad.
Imagine that I have a value that is generic over the monad:
m :: (Monad m) => m A -- 'A' is some concrete type
Now let's say that I specialize this value to a concrete monad transformer stack in two separate ways:
m1 :: T M A
m1 = m
m2 :: T M A
m2 = lift m
... where M and T M are monads, and T is a monad transformer:
instance Monad M where ...
instance (Monad m) => Monad (T m) where ...
instance MonadTrans T where ...
... and those instances obey the monad laws and monad transformer laws.
Can we deduce that:
m1 = m2
... knowing nothing about m other than its type?
This is just a long-winded way of asking if lift m is a valid substitution for m, assuming that both type-check. It is a little bit difficult to phrase the question because it requires m type-checking as two separate monads before and after the substitution. As far as I can tell, the only way such a substitution would type-check is if m is generic over the monad.
My vague intuition is that the substitution should always be correct, but I'm not sure that my intuition is correct, or how to prove it if it is correct.
If m :: Monad m => m A, then m must be equivalent to return x for some x :: A, because the only ways you have to get anything :: m x are return and (>>=). But in order to use (>>=) you must be able to produce some m y, which you can either do with return or with another application of (>>=). Either way you have to use return eventually, and the monad laws guarantee that the whole expression will be equivalent to return x.
(If m is completely polymorphic over the monad, then you must able to use it at m ~ Identity, so it can't use any fancy monad tricks, unless you pass it an argument. This sort of trick is used e.g. here and here.)
Given that m = return x, we know by the monad transformer laws (lift . return = return) that lift m = m.
Of course, this is only true for this particular type. If you have, say, m :: MonadState S m => m A, then m could easily be different from lift m -- for example, with a type like StateT A (State A) A, get and lift get will be different.
(And of course all of this is ignoring ⊥. Then again, if you don't, most monads don't obey the laws anyway.)
I believe this is a sloppy inductive proof that your m is equivalent to lift m.
I think we have to try to prove something about m (or rather, about all possible values of type (Monad m) => m A). If we consider Monad as consisting of bind and return only, and ignore bottom and fail then your m must at the top level be one of:
mA = return (x)
mB = (mX >>= f)
For mA the two forms of m are equivalent by the monad transformer law:
lift (return (x)) = return (x)
That's the base case. Then we're left with the second transformer law to reason about mB:
lift (mX >>= f) = lift mX >>= (lift . f)
and where we'd like to prove that that our mB is equal to that expansion:
mX >>= f = lift mX >>= (lift . f)
we assume that the left side of bind is equivalent (mX = lift mX) since that's our inductive hypothesis (right?).
So then we're left to prove f = lift . f by figuring out what f has to look like:
f :: a -> m b
f = \a -> (one of our forms mA or mB)
and lift . f looks like:
f = \a -> lift (one of our forms mA or mB)
Which leaves us back with our hypothesis:
m = lift m
I have become rather interested in how computation is modeled in Haskell. Several resources have described monads as "composable computation" and arrows as "abstract views of computation". I've never seen monoids, functors or applicative functors described in this way. It seems that they lack the necessary structure.
I find that idea interesting and wonder if there are any other constructs that do something similar. If so, what are some resources that I can use to acquaint myself with them? Are there any packages on Hackage that might come in handy?
Note: This question is similar to
Monads vs. Arrows and https://stackoverflow.com/questions/2395715/resources-for-learning-monads-functors-monoids-arrows-etc, but I am looking for constructs beyond funtors, applicative functors, monads, and arrows.
Edit: I concede that applicative functors should be considered "computational constructs", but I'm really looking for something I haven't come across yet. This includes applicative functors, monads and arrows.
Arrows are generalized by Categories, and so by the Category typeclass.
class Category f where
(.) :: f a b -> f b c -> f a c
id :: f a a
The Arrow typeclass definition has Category as a superclass. Categories (in the haskell sense) generalize functions (you can compose them but not apply them) and so are definitely a "model of computation". Arrow provides a Category with additional structure for working with tuples. So, while Category mirrors something about Haskell's function space, Arrow extends that to something about product types.
Every Monad gives rise to something called a "Kleisli Category" and this construction gives you instances of ArrowApply. You can build a Monad out of any ArrowApply such that going full circle doesn't change your behavior, so in some deep sense Monad and ArrowApply are the same thing.
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)
instance Monad m => Arrow (Kleisli m) where
arr f = Kleisli (return . f)
first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
Actually every Arrow gives rise to an Applicative (universally quantified to get the kinds right) in addition to the Category superclass, and I believe the combination of the appropriate Category and Applicative is enough to reconstruct your Arrow.
So, these structures are deeply connected.
Warning: wishy-washy commentary ahead. One central difference between the Functor/Applicative/Monad way of thinking and the Category/Arrow way of thinking is that while Functor and its ilk are generalizations at the level of object (types in Haskell), Category/Arrow are generelazation of the notion of morphism (functions in Haskell). My belief is that thinking at the level of generalized morphism involves a higher level of abstraction than thinking at the level of generalized objects. Sometimes that is a good thing, other times it is not. On the other-hand, despite the fact that Arrows have a categorical basis, and no one in math thinks Applicative is interesting, it is my understanding that Applicative is generally better understood than Arrow.
Basically you can think of "Category < Arrow < ArrowApply" and "Functor < Applicative < Monad" such that "Category ~ Functor", "Arrow ~ Applicative" and "ArrowApply ~ Monad".
More Concrete Below:
As for other structures to model computation: one can often reverse the direction of the "arrows" (just meaning morphisms here) in categorical constructions to get the "dual" or "co-construction". So, if a monad is defined as
class Functor m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
(okay, I know that isn't how Haskell defines things, but ma >>= f = join $ fmap f ma and join x = x >>= id so it just as well could be)
then the comonad is
class Functor m => Comonad m where
extract :: m a -> a -- this is co-return
duplicate :: m a -> m (m a) -- this is co-join
This thing turns out to be pretty common also. It turns out that Comonad is the basic underlying structure of cellular automata. For completness, I should point out that Edward Kmett's Control.Comonad puts duplicate in a class between functor and Comonad for "Extendable Functors" because you can also define
extend :: (m a -> b) -> m a -> m b -- Looks familiar? this is just the dual of >>=
extend f = fmap f . duplicate
--this is enough
duplicate = extend id
It turns out that all Monads are also "Extendable"
monadDuplicate :: Monad m => m a -> m (m a)
monadDuplicate = return
while all Comonads are "Joinable"
comonadJoin :: Comonad m => m (m a) -> m a
comonadJoin = extract
so these structures are very close together.
All Monads are Arrows (Monad is isomorphic to ArrowApply). In a different way, all Monads are instances of Applicative, where <*> is Control.Monad.ap and *> is >>. Applicative is weaker because it does not guarantee the >>= operation. Thus Applicative captures computations that do not examine previous results and branch on values. In retrospect much monadic code is actually applicative, and with a clean rewrite this would happen.
Extending monads, with recent Constraint kinds in GHC 7.4.1 there can now be nicer designs for restricted monads. And there are also people looking at parameterized monads, and of course I include a link to something by Oleg.
In libraries these structures give rise to different type of computations.
For example Applicatives can be used to implement static effects. With that I mean effects, which are defined at forehand. For example when implementing a state machine, rejecting or accepting an input state. They can't be used to manipulate their internal structure in terms of their input.
The type says it all:
<*> :: f (a -> b) -> f a -> f b
It is easy to reason, the structure of f cannot be depend om the input of a. Because a cannot reach f on the type level.
Monads can be used for dynamic effects. This also can be reasoned from the type signature:
>>= :: m a -> (a -> m b) -> m b
How can you see this? Because a is on the same "level" as m. Mathematically it is a two stage process. Bind is a composition of two function: fmap and join. First we use fmap together with the monadic action to create a new structure embedded in the old one:
fmap :: (a -> b) -> m a -> m b
f :: (a -> m b)
m :: m a
fmap f :: m a -> m (m b)
fmap f m :: m (m b)
Fmap can create a new structure, based on the input value. Then we collapse the structure with join, thus we are able to manipulate the structure from within the monadic computation in a way that depends on the input:
join :: m (m a) -> m a
join (fmap f m) :: m b
Many monads are easier to implement with join:
(>>=) = join . fmap
This is possible with monads:
addCounter :: Int -> m Int ()
But not with applicatives, but applicatives (and any monad) can do things like:
addOne :: m Int ()
Arrows give more control over the input and the output types, but for me they really feel similar to applicatives. Maybe I am wrong about that.