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

Al Zohali zohl at fmap.me
Mon May 15 21:09:14 UTC 2017


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?


More information about the Haskell-Cafe mailing list