Scoped type variables require explicit foralls. Why?

后端 未结 1 1330
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-02 09:03

If you want to use GHC\'s lexically scoped type variables, you also have to use explicit universal quantification. That is, you have to add forall declarations to y

相关标签:
1条回答
  • 2021-02-02 09:38

    Yes, the quantifier is meaningful and is required for the types to make sense.

    First note that there's really no such thing as an "unquantified" type signature in Haskell. Signatures without a forall are really implicitly quantified. This code ...

    f :: [a] -> [a]                         -- No `forall` here ...
    f (x:xs) = xs ++ [x :: a]               -- ... or here.
    

    ... really means this:

    f :: forall a . [a] -> [a]              -- With a `forall` here ...
    f (x:xs) = xs ++ [x :: forall a . a]    -- ... and another one here.
    

    So let's figure out what this says. The important thing is to notice that the type variables named a in the signatures for f and for x are bound by separate quantifiers. This means that they are different variables, despite sharing a name. So the above code is equivalent to this:

    f :: forall a . [a] -> [a]
    f (x:xs) = xs ++ [x :: forall b . b]    -- I've changed `a` to `b`
    

    With the names differentiated, it's now clear not only that the type variables in the signatures for f and x are unrelated, but that the signature for x claims that x can have any type. But this is impossible, since x must have the particular type bound to a when f is applied to an argument. And indeed the type-checker rejects this code.

    On the other hand, with a single forall in the signature for f ...

    f :: forall a . [a] -> [a]              -- A `forall` here ...
    f (x:xs) = xs ++ [x :: a]               -- ... but not here.
    

    ... the a in the signature on x is bound by the quantifier at the beginning of f's type signature, so this a represents the same type as the type represented by the variables called a in f's signature.

    0 讨论(0)
提交回复
热议问题