Understanding Haskell's RankNTypes

前端 未结 3 1272
[愿得一人]
[愿得一人] 2020-12-28 21:50

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)

r         


        
3条回答
  •  余生分开走
    2020-12-28 22:15

    In the normal case (forall n. Num n => (n -> n) -> (Int, Double)), we choose an n first and then provide a function. So we could pass in a function of type Int -> Int, Double -> Double, Rational -> Rational and so on.

    In the Rank 2 case ((forall n. Num n => n -> n) -> (Int, Double)) we have to provide the function before we know n. This means that the function has to work for any n; none of the examples I listed for the previous example would work.

    We need this for the example code given because the function f that's passed in is applied to two different types: an Int and a Double. So it has to work for both of them.

    The first case is normal because that's how type variables work by default. If you don't have a forall at all, your type signature is equivalent to having it at the very beginning. (This is called prenex form.) So Num n => (n -> n) -> (Int, Double) is implicitly the same as forall n. Num n => (n -> n) -> (Int, Double).

    What's the type of a function that works for any n? It's exactly forall n. Num n => n -> n.

提交回复
热议问题