Switching on RankNTypes
(without which these signatures won't get accepted, because they're not Haskell 98, says the User Guide), and -fprint-explicit-foralls
so I can see the quantification, consider:
foo :: b -> (Eq c => c) -- inferred foo :: forall {c} {b}. Eq c => b -> c
foo x = undefined
bar :: b -> (Eq b => b) -- inferred bar :: forall {b}. Eq b => b -> b
bar x = undefined
bar2 :: b -> (forall b. Eq b => b) -- bar2 :: forall {b1} {b}. Eq b1 => b -> b1
bar2 x = undefined
OK so far: these are all Rank 1 Types. GHC (version 8.6.5) has shunted the constraint to the front of the signature; for bar
'commonned' the scope of same-named b
; for bar2
not commonned the scope because there's an explicit forall
in the given signature, so that's name-shadowing.
barbar :: b -> (Eq b => b) -> (Show b => b) -- barbar :: forall {b}. Show b => b -> (Eq b => b) -> b
barbar x y = undefined
barbar2 :: b -> Eq b => b -> (Show b => b) -- barbar2 :: forall {b}. (Eq b, Show b) => b -> b -> b
barbar2 x y = undefined
What's going on with the inferred signature for barbar
? That nested -> (Eq b => b) ->
is not H98. Does that mean the b
is not commonned? No:
*Main> barbar 'c' True
<interactive>:36:12: error:
* Couldn't match expected type `Char' with actual type `Bool'
So barbar, barbar2
are Rank 1 and have the same effective signature -- or do they?
Addit: (in response to answers)
barbar4 :: b -> (Eq b => b -> (Show b => b)) -- barbar4 :: forall {b}. (Eq b, Show b) => b -> b -> b
barbar4 x y = undefined
barbar, barbar4
are equivalent? So Eq b =>
in barbar
scopes over everything to the right. Then I can see that's Rank-1. Whereas the closing parens nested in the given signature for barbar2
is not merely decoration.