多态类型的包含

时间:2014-11-07 17:23:57

标签: haskell types ml

‘Practical type inference for arbitrary-rank types’中,作者谈到包含

3.3 Subsumption

我在阅读时尝试在GHCi中测试一些东西,但即使g k2意图进行类型检查,当我尝试使用GHC 7.8.3时也不会这样:

λ> :set -XRankNTypes
λ> let g :: ((forall b. [b] -> [b]) -> Int) -> Int; g = undefined
λ> let k1 :: (forall a. a -> a) -> Int; k1 = undefined
λ> let k2 :: ([Int] -> [Int]) -> Int; k2 = undefined
λ> :t g k1

<interactive>:1:3: Warning:
    Couldn't match type ‘a’ with ‘[a]’
      ‘a’ is a rigid type variable bound by
          the type forall a1. a1 -> a1 at <interactive>:1:3
    Expected type: (forall b. [b] -> [b]) -> Int
      Actual type: (forall a. a -> a) -> Int
    In the first argument of ‘g’, namely ‘k1’
    In the expression: g k1
g k1 :: Int
λ> :t g k2

<interactive>:1:3: Warning:
    Couldn't match type ‘[Int] -> [Int]’ with ‘forall b. [b] -> [b]’
    Expected type: (forall b. [b] -> [b]) -> Int
      Actual type: ([Int] -> [Int]) -> Int
    In the first argument of ‘g’, namely ‘k2’
    In the expression: g k2
g k2 :: Int

我还没有真正理解论文,但是,我仍然担心我误解了一些东西。这个类型检查应该吗?我的Haskell类型是错误的吗?

1 个答案:

答案 0 :(得分:17)

typechecker doesn't know when to apply the subsumption rule.

使用以下功能时可以告诉它。

Prelude> let u :: ((f a -> f a) -> c) -> ((forall b. f b -> f b) -> c); u f n = f n

这说明,给定特定类型转换的函数,我们可以通过自然转换forall b. f b -> f b创建函数。

然后我们可以在第二个例子上成功尝试。

Prelude> :t g (u k2)
g (u k2) :: Int

第一个例子现在也提供了更多信息。

Prelude> :t g (u k1)
    Couldn't match type `forall a. a -> a' with `[a0] -> [a0]'
    Expected type: ([a0] -> [a0]) -> Int
      Actual type: (forall a. a -> a) -> Int
    In the first argument of `u', namely `k1'
    In the first argument of `g', namely `(u k1)'

我不知道我们是否可以编写u的更通用版本;我们需要一个更少多态的约束级概念来编写像let s :: (a :<: b) => (a -> c) -> (b -> c); s f x = f x

这样的东西