The Reader monad
The request for a value of type e from the current environment This
can be expressed as a GADT because the type of values returned in
response to a (Reader e a) request is not any a; we expect in reply
the value of type
e, the value from the environment. So, the
return type is restricted: 'a ~ e'
One can also define this as
data Reader e v = (e ~ v) => Reader
^ without GADTs, using explicit coercion as is done here.
newtype Reader e v = Reader (e->v)
^ In the latter case, when we make the request, we make it as Reader
id. So, strictly speaking, GADTs are not really necessary.