While working my way through GHC extensions, I came across RankNTypes
at the School of Haskell, which had the following example:
main = print $ rankN (+1)
rankN :: (forall n. Num n => n -> n) -> (Int, Double)
rankN f = (f 1, f 1.0)
The article offered an alternative type for rankN
:
rankN :: forall n. Num n => (n -> n) -> (Int, Double)
The explanation of the difference is that
The latter signature requires a function from n to n for some Num n; the former signature requires a function from n to n for every Num n.
I can understand that the former type requires a signature to be what's in the parentheses or more general. I do not understand the explanation that the latter signature simply requires a function n -> n
for "some Num n
". Can someone elaborate and clarify? How do you "read" this former signature so that it sounds like what it means? Is the latter signature the same as simply Num n => (n -> n) -> (Int, Double)
without the need for forall
?