【问题标题】:Subsumption in polymorphic types多态类型中的包含
【发布时间】:2015-01-04 13:32:18
【问题描述】:

‘Practical type inference for arbitrary-rank types’,作者谈论包容

我在阅读时尝试在 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 类型错了吗?

【问题讨论】:

    标签: haskell types ml


    【解决方案1】:

    类型检查器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 -&gt; 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 :&lt;: b) =&gt; (a -&gt; c) -&gt; (b -&gt; c); s f x = f x

    【讨论】:

    • 这是 Haskell 没有认真对待自己的子类型化概念的一个很好的例子......但是当你需要它时,更明确一点通常也不错。
    • GHC,你让我失望了。我非常确定 GHC 做对了,我什至在此处删除的答案中掩盖了我的愚蠢错误。
    • 论文中描述的类型检查器确实知道何时应用包含规则。这显然只是GHC。我知道这一点,因为我在 Frege 中实现了该论文中描述的类型检查器,并且 Frege 类型检查器接受 g k2 没有抱怨。 (示例见此处:github.com/Frege/frege/issues/80#issuecomment-62257574
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-28
    • 2019-04-19
    • 2013-04-21
    • 2010-12-31
    • 1970-01-01
    • 2023-01-01
    相关资源
    最近更新 更多