[Haskell-cafe] Position of a constraint in a function's signature

William Yager will.yager at gmail.com
Mon May 15 22:55:30 UTC 2017

Disclaimer: My understanding of this may be out of date/incomplete. My
understanding of Haskell typing is largely based on
https://web.cecs.pdx.edu/~mpj/thih/thih.pdf which is old and doesn't
contain RankNTypes.


Why wouldn't it compile?

"C => T" means (or is equivalent to) "A function which takes an implicit
parameter C and returns a T". There's no particular reason this can't show
up on the RHS of a "->" arrow.

Admittedly, no one really uses typeclasses in this way, but it's not
fundamentally wrong.


I don't believe the former interpretation of baz is valid. The "a" on its
own and the one in "Show a" ought to be unified.

When you quantify an unquantified type, you do it over the *entire* type,
not just the variables that show up in constraints. There's no reason you
would insert a "forall" in the RHS of an arrow.


On Mon, May 15, 2017 at 4:09 PM, Al Zohali <zohl at fmap.me> wrote:

> Dear Cafe!
> I've encountered quite strange behaviour in GHC (v8.0.2) and I would
> like to ask you to give me a hint.
> Suppose we have the following functions:
> ----
> foo :: (Show a) => Int -> a -> [String]
> foo n = replicate n . show
> bar :: Int -> (Show a) => a -> [String]
> bar n = replicate n . show
> baz :: Int -> a -> (Show a) => [String]
> baz n = replicate n . show
> ----
> This won't compile, and that is ok. But if we add `RankNTypes`
> extension, this will compile and (:t) will give us the same signature
> for all three functions.
> There are two things I cannot get:
> 1) Why do this even compile?
> I saw constraints being defined either in the beginning of a signature
> or right after `forall` expression. I thought that it was a rule (or
> convention), but it's not. Is this way of declaring constraints (in
> the middle of a signature) discouraged or can be considered as a bug?
> 2) Even if this was supposed to be so, why was the constraint in `baz`
> hoisted to the top?
> There are at least two ways to interpret that signature:
> ----
> baz :: Int -> a -> forall a. (Show a) => [String]
> baz :: forall a. (Show a) => Int -> a -> [String]
> ----
> Is there any reason why the second one was chosen?
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170515/9c7d5a38/attachment.html>

More information about the Haskell-Cafe mailing list