Haskell synonym definition - haskell

Could someone explain me what the following synonim means and how to read it:
type TCM a = ErrorT String (StateT MyEnv IO) a
What I was able to understand up till now:
we say that we introduce new name for some type and now we say that we call it TCM and it has some parameter a
We have value constructor ErrorT (what makes ErrorT?) that takes three arguments: String, (StateT MyEnv IO) and a
(StateT MyEnv IO) - we say here that we have value constructor StateT and args MyEnv and IO. But what this type makes?
Am I right? Could anyone explain me how it works? Thanks for any responses.
Edit: Maybe someone could help me also with this. I have sth the following function in my program that evaluate Integer:
ms_exp :: Exp -> TCM ()
ms_exp (EInt integer) = do
return integer
and it have such error:
Couldn't match expected type `()' with actual type `Integer'
Any hints?

Well, the ErrorT type already had the a type parameter, if we wished, we could specialize it, that is, make type
type TCMInt = ErrorT String (StateT MyEnv IO) Int
However, we can leave it as a type parameter, as you did in your example.
No, ErrorT is not a value constructor, it is a type constructor. What makes an element of ErrorT? Well, that depends on what ErrorT is. I suppose it is Control.Monad.Error, and it is said that is is constructed by the runErrorT function.
Again, StateT is not a value constructor, it is a type constructor (created with newtype keyword acoording to this). As you can see from newtype State s a, the State type constructors expects two type names to construct a type, so your code passes MyEnv and IO, yielding the StateT MyEnv IO type.
To the update: your function expects to inject an element of () into the TCM monad by doing return () while you do return integer. You need either return () or change the type of ms_exp to Exp -> TCM Integer.

Related

How to write this simple Monad?

I try to write this:
data A=A Int deriving Show
instance Monad A where
return x=A x
A x>>=f=f x
main=print a where a=A 1
I learn it from the book 《Learn You a Haskell for Great Good》:
instance Monad Maybe where
return x = Just x
Nothing >>= f = Nothing
Just x >>= f = f x
fail _ = Nothing
but got error:
a.hs:3:16: error:
? Expected kind ‘* -> *’, but ‘A’ has kind ‘*’
? In the first argument of ‘Monad’, namely ‘A’
In the instance declaration for ‘Monad A’
so how to write it? When finish, I can write
A 1>>\x->x+1
and get A 2
You can't make A an instance of Monad given its current definition.
The error message tells you that the compiler expects something of the kind * -> *. This means a type that takes a type as input, like Maybe a, IO a, or [] a. In other words, the type must be parametrically polymorphic.
In oder to get an intuitive sense of this, consider return, which has the type:
return :: a -> m a
The type argument a is unconstrained. This means that you should be able to take any value of type a and turn it into a value of the polymorphic type.
If I give you the Boolean value False, which A value will you construct from it? If I give you the string "foo", which A value will you construct from it? If I give you the function id, which A value will you construct from it?
If you want to make your type a Monad instance, you must give it a type parameter, at least like this:
data A a = A Int deriving Show
Here, the a type parameter is in the phantom role; it's not used, but now you're at least able to make it a Functor. This version of A is isomorphic to the Const functor. You can make it a Functor and Applicative instance, but can you make it a Monad?

Type inference seems like a magic

I have following code snippet and could not configure it out, how it works:
embedded :: MaybeT (ExceptT String (ReaderT () IO)) Int
embedded = return 1
How it is possible to give only a number and get such as type signature back? How does the compiler do that?
The choice of wording is a bit unfortunate. It's not the case that the expression return 1 gives back the type signature MaybeT (ExceptT String (ReaderT () IO)) Int.
As n.m. writes in the comments, if you don't supply a type, the expression is much more general:
Prelude> embedded = return 1
Prelude> :type embedded
embedded :: (Num a, Monad m) => m a
By annotating with a type, you explicitly state that you want something less general than that.
Specifically, you state that you want the type MaybeT (ExceptT String (ReaderT () IO)) Int.
How does return work? MaybeT m a is a Monad when m is a Monad, and return is defined like this:
return = lift . return
The right-hand return is the return function that belongs to the 'inner' Monad, whereas lift is defined by MonadTrans and lifts the underlying monadic value up to MaybeT.
That explains how a MaybeT value is created, but isn't the whole story.
In this case, the 'inner' Monad is ExceptT String (ReaderT () IO), which is another Monad (in fact, another MonadTrans). return is defined like this:
return a = ExceptT $ return (Right a)
Notice that this is another nested return, where the right-hand return belongs to yet another nested Monad.
In this case, the nested Monad is ReaderT () IO - another MonadTrans. It defines return like this:
return = lift . return
Yet another nested return, where the right-hand return is the return defined for IO (in this particular case).
All of this is parametrised with a, which in this case you've constrained to Int.
So return 1 first takes the pure value 1 and packages it in IO Int. This then gets lifted to ReaderT () IO Int, which again gets packaged into an ExceptT String (ReaderT () IO) Int. Finally, this values gets lifted to MaybeT.

Haskell: function signature

This program compiles without problems:
bar :: MonadIO m
=> m String
bar = undefined
run2IO :: MonadIO m
=> m String
-> m String
run2IO foo = liftIO bar
When I change bar to foo (argument name),
run2IO :: MonadIO m
=> m String
-> m String
run2IO foo = liftIO foo
I get:
Couldn't match type ‘m’ with ‘IO’
‘m’ is a rigid type variable bound by
the type signature for run2IO :: MonadIO m => m String -> m String
...
Expected type: IO String
Actual type: m String ...
Why are the 2 cases are not equivalent?
Remember the type of liftIO:
liftIO :: MonadIO m => IO a -> m a
Importantly, the first argument must be a concrete IO value. That means when you have an expression liftIO x, then x must be of type IO a.
When a Haskell function is universally quantified (using an implicit or explicit forall), then that means the function caller chooses what the type variable is replaced by. As an example, consider the id function: it has type a -> a, but when you evaluate the expression id True, then id takes the type Bool -> Bool because a is instantiated as the Bool type.
Now, consider your first example again:
run2IO :: MonadIO m => m Integer -> m Integer
run2IO foo = liftIO bar
The foo argument is completely irrelevant here, so all that actually matters is the liftIO bar expression. Since liftIO requires its first argument to be of type IO a, then bar must be of type IO a. However, bar is polymorphic: it actually has type MonadIO m => m Integer.
Fortunately, IO has a MonadIO instance, so the bar value is instantiated using IO to become IO Integer, which is okay, because bar is universally quantified, so its instantiation is chosen by its use.
Now, consider the other situation, in which liftIO foo is used, instead. This seems like it’s the same, but it actually isn’t at all: this time, the MonadIO m => m Integer value is an argument to the function, not a separate value. The quantification is over the entire function, not the individual value. To understand this more intuitively, it might be helpful to consider id again, but this time, consider its definition:
id :: a -> a
id x = x
In this case, x cannot be instantiated to be Bool within its definition, since that would mean id could only work on Bool values, which is obviously wrong. Effectively, within the implementation of id, x must be used completely generically—it cannot be instantiated to a specific type because that would violate the parametricity guarantees.
Therefore, in your run2IO function, foo must be used completely generically as an arbitrary MonadIO value, not a specific MonadIO instance. The liftIO call attempts to use the specific IO instance, which is disallowed, since the caller might not provide an IO value.
It is possible, of course, that you might want the argument to the function to be quantified in the same way as bar is; that is, you might want its instantiation to be chosen by the implementation, not the caller. In that case, you can use the RankNTypes language extension to specify a different type using an explicit forall:
{-# LANGUAGE RankNTypes #-}
run3IO :: MonadIO m => (forall m1. MonadIO m1 => m1 Integer) -> m Integer
run3IO foo = liftIO foo
This will typecheck, but it’s not a very useful function.
In the first, you're using liftIO on bar. That actually requires bar :: IO String. Now, IO happens to be (trivially) an instance on MonadIO, so this works – the compiler simply throws away the polymorphism of bar.
In the second case, the compiler doesn't get to decide what particular monad to use as the type of foo: it's fixed by the environment, i.e. the caller can decide what MonadIO instance it should be. To again get the freedom to choose IO as the monad, you'd need the following signature:
{-# LANGUAGE Rank2Types, UnicodeSyntax #-}
run2IO' :: MonadIO m
=> (∀ m' . MonadIO m' => m' String)
-> m String
run2IO' foo = liftIO foo
... however I don't think you really want that: you might then as well write
run2IO' :: MonadIO m => IO String -> m String
run2IO' foo = liftIO foo
or simply run2IO = liftIO.

Make type showable.

How to make type Showable?
type InterpreterMonad = StateT (Env, Env) (ErrorT String IO ) ()
Normally, I would type deriving Show but I have a type not newtype or data.
P.S. How to write above with newtype?
type creates a type synonym. If you want to create an instance, you must create it for the target of the type synonym – in this case, StateT (Env, Env) (ErrorT String IO ) (). However, GHC can't derive a Show instance for StateT types because StateT is a wrapper around a function type and GHC can't derive Show for function types.
You could write a newtype as follows:
newtype InterpreterMonad = MkInterpreterMonad (StateT (Env, Env) (ErrorT String IO ) ())
but this won't allow you to derive Show either, since InterpreterMonad is now a wrapper around a wrapper around a function type.

Haskell - Ambiguous type variable

I am having trouble with ambiguous types in Haskell. I started out with the following:
module GameState
( GameState(..)
, GameStateMonad
, module Control.Monad.Trans
, module Control.Monad.Trans.State.Lazy
, Blank(..)
) where
import Control.Monad.Trans
import Control.Monad.Trans.State.Lazy
type GameStateMonad a b = StateT a IO b
class GameState a where
update :: Double -> GameStateMonad a ()
update deltaTime = return ()
draw :: GameStateMonad a ()
draw = return ()
getNextState :: GameState b => GameStateMonad a (Maybe b)
getNextState = return Nothing
isStateFinished :: GameStateMonad a Bool
isStateFinished = return True
-- This is just a dummy data and instance declaration to demonstrate the error
data Blank = Blank
instance GameState Blank
Then when I try to run the following in ghci:
runStateT getNextState Blank
I get:
Ambiguous type variable `b0' in the constraint:
(GameState b0) arising from a use of `getNextState'
Probable fix: add a type signature that fixes these type variable(s)
...
I thought it was complaining that my default implementation of the getNextState function didn't specify a concrete type, so I tried the following:
getNextState :: GameState b => GameStateMonad a (Maybe b)
getNextState = return (Nothing :: Maybe Blank)
Unfortunately I got this error while compiling:
Could not deduce (b ~ Blank)
from the context (GameState a)
bound by the class declaration for `GameState'
at GameState.hs:(14,1)-(25,33)
or from (GameState b)
bound by the type signature for
getNextState :: GameState b => GameStateMonad a (Maybe b)
at GameState.hs:22:5-50
`b' is a rigid type variable bound by
the type signature for
getNextState :: GameState b => GameStateMonad a (Maybe b)
at GameState.hs:22:5
...
But I found that adding a type signature when I call getNext state allows the code to run:
runStateT (getNextState :: GameStateMonad Blank (Maybe Blank)) Blank
Unfortunately this stops me from making generic code to handle game states. It also makes little sense to me. What's the point in returning a polymorphic type if you have to give it an explicit type after it's returned? The original issue is also really confusing to me because I can make a function as follows:
test :: Num a => Maybe a
test = Nothing
And have no problems running it. Shouldn't this complain about ambiguous types like my original code? Also when giving the return value an explicit type I cannot compile it, like before:
test :: Num a => Maybe a
test = Nothing :: Maybe Int
I don't see why this is a problem. Int is an instance of type Num so the type of the function is correct.
I have four questions:
Why does giving an explicit type when returning an element of a typeclass cause a compile error?
Why does returning an ambiguous Maybe value inside of getNextState cause an error but inside test it does not?
Why does this error occur without me calling a function on the returned polymorphic data, as explained here?
In the link above, the answer mentions that "[you get this error] because you have something that produces a polymorphic result, then apply a function that takes a polymorphic argument to that result, such that the intermediate value's type is unknown". Doesn't this mean that functions that return a polymorphic result are essentially useless?
Thanks.
Cat Plus Plus has already explained why
getNextState :: GameState b => GameStateMonad a (Maybe b)
getNextState = return (Nothing :: Maybe Blank)
doesn't work, so I can be short on that. The type signature promises that getNextState can deliver a value of type Maybe b for whatever type b the caller demands. It's the caller of the function who decides what type it shall return if a function has polymorphic return type. So the signature promises "whatever you want, as long as it's a GameState instance", but the implementation says "No, I don't care what you ordered, I return a Blank".
Ambiguous type variable `b0' in the constraint:
(GameState b0) arising from a use of `getNextState'
Probable fix: add a type signature that fixes these type variable(s)
from typing
runStateT getNextState Blank
at the ghci prompt. If you ask ghci for the type of that, it will tell you
runStateT getNextState Blank :: GameState b => IO (Maybe b)
(no guarantees about the choice of type variable). But there is no context, so ghci doesn't know which type to instantiate b with. And so it doesn't know which implementation of getNextState it should call [or, which dictionary it should pass, if we look at GHC's implementation of type classes]. It has no way of resolving that ambiguity, so it tells you about it and suggests how you could resolve it.
test :: Num a => Maybe a
test = Nothing
Yes, that's in principle the same problem, when you type test at the ghci prompt. But there are special rules for resolving ambiguous type variables when there is one numeric class involved (where ambiguities are most frequent, literals are already ambiguous), and all involved constraints are simple and concern classes of the Prelude or the standard libraries. In that case, ambiguous type variables are instantiated by defaulting, so ghci would choose to instantiate a with Integer and print the Nothing of the type Maybe Integer.
Your GameState class is not defaultable, that's the difference between these examples.
Why does this error occur without me calling a function on the returned polymorphic data, as explained here?
Because you're not calling any function that would determine the type. If you had a function of type
foo :: Blank -> Int
and typed
runStateT getNextState Blank >>= print . maybe 0 foo
the use of foo would determine b and all would be swell.
The problem would however not be solved but exacerbated, if you called a polymorphic function (whose argument type cannot be inferred from its result type), as in the linked example. Then the ambiguous type is no longer reachable from the outside, and it can never be resolved. Then the only way is to provide a type signature that resolves the ambiguity.
Doesn't this mean that functions that return a polymorphic result are essentially useless?
Oh no, they are immensely useful. Look at read, or fromInteger, realToFrac, ...
The point is, that the type at which they shall be used must somehow be determined where they are used. Most of the time that is done by the calling context, but sometimes an explicit type signature is necessary.
I'm not sure what you're trying to achieve by making GameState a typeclass. You might be too much in OOP mindset here — typeclasses are not OOP classes. A set of game states will probably be closed, so it might make more sense to just make it a single ADT.
Why does giving an explicit type when returning an element of a typeclass cause a compile error?
Look at your function's signature: GameState b => GameStateMonad a (Maybe b). Now remember that this implies forall b. GameState b => GameStateMonad a (Maybe b).
Implementation of the function cannot decide what b is — it must work for all of them (as long as they fit in constraints), because it's up for the caller to decide.
That's why return (Nothing :: Maybe Blank) is an error — it doesn't work for all types b — it only works for Blank. "Could not deduce (b ~ Blank)" means GHC can't prove type equality here. Same thing goes for Nothing :: Maybe Int. And that's also why adding type signature in the call site works.
I'll write something on ambiguities later maybe. I'm still pretty sure you're overengineering this code anyway, so the solution is to not do that.

Resources