Understanding `kind` of MonadTrans - haskell

Looking at the kind of Monad:
ghci>:k Monad
Monad :: (* -> *) -> Constraint
I believe that's because it takes an a from m a, and returns the Monad constraint.
Looking at MonadTrans's *kind, I see:
ghci>:i MonadTrans
class MonadTrans (t :: (* -> *) -> * -> *) where
lift :: Monad m => m a -> t m a
-- Defined in `Control.Monad.Trans.Class'
instance MonadTrans MaybeT
-- Defined in `Control.Monad.Trans.Maybe'
So, the first (* -> *) comes from Monad's kind, I believe. But what about the * -> *?

The second * -> * also comes from Monad's kind! A monad transformer takes a type argument that is a Monad (or at least a type that has the kind of a Monad) and produces a new type which is a Monad (which also has the kind of a Monad).
* -> * -- a Monad
(* -> *) -> * -> * -- Something that takes a Monad and makes a new Monad.
* -> * -- also a Monad

Related

Monad Transformer missing parameter (?)

I've got this type alias:
type Board a = ReaderT String (StateT String IO) a
I know that StateT has the kind * -> (* -> *) -> * -> * so it should get three parameters. But in the above example, StateT only receives String and the IO-Monad.
Now I'm wondering where the missing parameter is passed to StateT.
Same goes for IO which should get one parameter but doesn't get any.
If you look at the definition of ReaderT, you will see that its second parameter is itself applied to its last parameter:
newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
^^^
right here
Which means that its second parameter m must have kind m :: * -> *. And this is exactly what you get if you apply only two, not three, parameters to StateT:
StateT :: * -> (* -> *) -> * -> *
StateT x y :: * -> *
(where x :: * and y :: * -> *)
When substituting the definition of ReaderT in your type Board, you'll get:
(1) type Board a = ReaderT String (StateT String IO) a
-- Substituting ReaderT definition (pseudocode)
(2) type Board a = { runReaderT :: String -> StateT String IO a }
^^^^^^^^^^^^^^^^^^
Look, StateT has all its three parameters!
You correctly observe that
StateT has the kind * -> (* -> *) -> * -> *
and the same is true of ReaderT.
So it takes 3 "parameters" as you call them. The first is String, of kind *, and the third is a, again of kind *. While the second must be of kind * -> *.
And that is given in your example by StateT String IO. So although there is in one sense a "missing parameter" of StateT, this needs to be "missing" in order to get something of kind * -> * - if you tried something like type Board a = ReaderT String (StateT String IO Int) a, this would fail with a "kind error", precisely because ReaderT's second type argument needs to be of kind * -> *, not of kind * which StateT String IO Int would have.
The same applies to why IO is used on its own rather than something of the form IO a. StateT String (IO Int) wouldn't work because StateT needs to apply to something of kind * -> * as its second type argument - IO has this kind but IO Int (or anything of the form IO a) does not.
To take a step back, monad transformers like ReaderT and StateT transform another monad, and a monad must always be of kind * -> *. IO is a monad, and so is StateT String IO. But IO Int and StateT String IO Int are not monads - and not for failing the monad laws or anything like that, but for a much more fundamental meaning, they are the wrong kind. (They are "concrete types" - types which have values - rather than "type constructors" that take another type as an argument.)

Higher kinded type on typeclass? [duplicate]

If I inspect the kind of Maybe I get this:
λ> :k Maybe
Maybe :: * -> *
Now, if I inspect the kind of Monad I get this:
λ> :k Monad
Monad :: (* -> *) -> Constraint
What is Constraint there and why it is needed ? Why not just this * -> * ?
Unlike Maybe, Monad is not a type; it is a typeclass.
The same goes for other typeclasses:
Num :: * -> Constraint
Functor :: (* -> *) -> Constraint
Bifunctor :: (* -> * -> *) -> Constraint
Where * represents concrete types (such as Bool or Int), -> represent higher-kinded types (such as Maybe), and Constraint represents the idea of a type constraint. This is why:
As we know we can't make a signature like this:
return :: a -> Monad a -- This is nonsense!
Because Monad should be used as a constraint, to say that, 'this must be a monad to work':
return :: (Monad m) => a -> m a
We do this because we know that return can't work on any old type m, so we define the behaviour of return for different types under the name Monad. In other words, there is no single thing that can be called a Monad, but only behaviour that can be called Monadic.
For this reason, we have created this type constraint, saying that we must have pre-defined something as a Monad to use this function. This is why the kind of Monad is (* -> *) -> Constraint - it itself is not a type!
Maybe is an instance of Monad. This means that somewhere, someone has written:
instance Monad Maybe where
(>>=) = ... -- etc
...and defined how Maybe should behave as a Monad. This is why we can use Maybe with functions or types that have the prefix constraint Monad m => .... This is essentially where one defines the constraint applied by Monad.
Constraint is the kind of e.g. Show Int, Monad Maybe, and Monoid [a]. Roughly, it is the kind of everything that can occur on the left side of => in type annotations.
Now since
Show Int :: Constraint
and Int is a type, i.e.
Int :: *
we can assign a functional kind to Show as follows
Show :: * -> Constraint
^-- the result kind
^-- the kind of Int
In your case it just happens that a Monad takes argument like Maybe, so
Maybe Int :: *
Maybe :: * -> *
Monad :: (* -> *) -> Constraint
^-- the result kind
^-- the kind of Maybe

Haskell: need to understand signature of Functor

Can some body explain me the signature of Functor.
Prelude> :info Functor
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
I don't understand what * means.
* is the syntax used by Haskell for kinds
In this case it means that f is higher-kinded (think functions on the type level)
Here f is taking one type (the first *) and is producing another type (the second *)
you can basically forget all this here and just read it as:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
but it's a nice documentation IMO and there are quite a few classes that are more complicated and the kind-signature is really helpful - for example:
class MonadTrans (t :: (* -> *) -> * -> *) where
lift :: Monad m => m a -> t m a
-- Defined in `Control.Monad.Trans.Class'
Here t takes a type-constructor itself (the Monad) together with another type and produces a type again.

Kind mis-match in instance of Maybe

I have a definition of class
class Functor f => Pointed f where
pure :: a -> f a
And now I would like to make instance for Maybe. Why doesn't this work?
instance Pointed (Maybe s) where
pure Nothing = Nothing
pure (Just a) = a
class Functor f where
fmap :: (a->b) -> f a -> f b
Error is:
Kind mis-match
The first argument of `Pointed' should have kind `* -> *',
but `Maybe s' has kind `*'
In the instance declaration for `Pointed (Maybe s)'
Failed, modules loaded: none.
In the definition of Pointed, f has kind * -> * so you need to provide a type constructor with the same kind. Maybe has that kind, while (Maybe s) has kind *. If you substitute Maybe for f in the definition of pure you get:
pure :: a -> Maybe a
Your definition should therefore look like:
instance Pointed Maybe where
pure a = Just a
The kind * -> * is inferred for f due to the rules for kind inference. a is assumed to have kind * as it is a function parameter (which has kind * -> * -> *). f a should have kind * so f has kind * -> *.
In the definition of Pointed, Functor f => is a class context and declares that Functor is a superclass of Pointed. This means that all instances of Pointed must also be instances of Functor.
Maybe is already an instance of Functor so you don't need to define it yourself.

How do I make MonadRandom a Functor?

It seems that MonadRandom from the random-fu package is not a Functor, as I am getting errors like:
Could not deduce (Functor m) arising from a use of ‘_1’
from the context (MonadRandom m)
I've tried adding the following code:
instance Functor MonadRandom where
fmap = liftM
instance Applicative MonadRandom where
pure = return
(<*>) = ap
but I get the error:
The first argument of ‘Functor’ should have kind ‘* -> *’,
but ‘MonadRandom’ has kind ‘(* -> *) -> Constraint’
In the instance declaration for ‘Functor MonadRandom’
The first argument of ‘Applicative’ should have kind ‘* -> *’,
but ‘MonadRandom’ has kind ‘(* -> *) -> Constraint’
In the instance declaration for ‘Applicative MonadRandom’
MonadRandom is a class, not a type with kind * -> *, like Maybe for example. Usually, you would use something like
instance MonadRandom m => Functor m where
fmap = liftM
instance MonadRandom m => Applicative m where
pure = return
(<*>) = ap
However, in this case the instances of MonadRandom are already functors, so now the instances are ambiguous! Instead, you should to add the Functor constraint at your function:
yourFunction :: (MonadRandom m, Functor m) => ...
-- instead of yourFunction :: (MonadRandom m) => ...

Resources