【问题标题】:Why are type instances (a->a) and (a->a->a) conflicting in GHC 7.8?为什么类型实例 (a->a) 和 (a->a->a) 在 GHC 7.8 中会发生冲突?
【发布时间】:2013-08-22 00:29:19
【问题描述】:

hmatrix 包包含以下类型族代码:

type family BoundsOf x

type instance BoundsOf (a->a) = Int
type instance BoundsOf (a->a->a) = (Int,Int)

在 GHC 7.6 上,这编译得很好。

在 GHC 7.7(导致 7.8)上,我们得到:

lib/Numeric/ContainerBoot.hs:515:15:
    Conflicting family instance declarations:
      BoundsOf (a -> a) -- Defined at lib/Numeric/ContainerBoot.hs:515:15
      BoundsOf (a -> a -> a)
        -- Defined at lib/Numeric/ContainerBoot.hs:516:15

这里的“冲突”是什么意思?我看不出这些实例的问题。


更新:这是一个最小的例子Test.hs

{-# LANGUAGE TypeFamilies #-}
module Test where

type family BoundsOf x

type instance BoundsOf (a->a) = Int
type instance BoundsOf (a->a->a) = (Int,Int)

尝试一下:

ghci Test.hs       # 7.6, all fine
ghci-7.7 Test.hs   # fails

【问题讨论】:

  • 确实看起来像一个错误。
  • 一个叫做 goldfire 的人在 GHC 票证中添加了一个很好的解释,说明为什么这不应该起作用。
  • 我可以看到一个理解金火的评论,但我觉得它令人不安。对于a 的任何有限实例化,类型(a->a)(a->a->a) 不能相同。所以应该没问题。但事实并非如此,这意味着无限类型必须潜入 ghc。
  • @augustss 如果我对评论的理解正确,那么您可以写type instance Family (OthertypeFamily a),并且由于OtherTypeFamily 不是类型构造函数而只是类型函数,因此TyFun a a = TyFun a (TyFun a) 可能。那么问题将是解析type instance Family (T a b) 的代码不知道T 是类型构造函数还是类型族。我不知道能够将类型族用于其他族实例是否是个好主意,但似乎有人认为这是

标签: haskell type-families


【解决方案1】:

Akio Takano 设法构建了一个示例程序,在 GHC 7.6 中使用类型族声明将 Int 强制转换为 IO String

type family F a
type instance F (a -> a) = Int
type instance F (a -> a -> a) = IO String

http://ghc.haskell.org/trac/ghc/ticket/8162https://github.com/takano-akio/type-family-overlap

【讨论】:

    【解决方案2】:

    在我看来,它更像是 GHC 7.6 TBH 中的一个错误。

    如果你去掉函数类型的语法糖,你所拥有的是

    type instance BoundsOf (((->) a) a) = Int
    type instance BoundsOf (((->) a) (((->) a) a)) = (Int, Int)
    

    看起来很矛盾……

    现在,如果我尝试使用另一个类型构造函数而不是 ((->) a) 来实现相同的技巧,我也会收到来自 GHC 7.6 的错误:

    {-# LANGUAGE TypeFamilies #-}
    type family BoundsOf x
    
    type instance BoundsOf (Maybe a) = Int
    type instance BoundsOf (Maybe (Maybe a)) = (Int, Int)
    

    结果:

    tyfams.hs:4:15:
        Conflicting family instance declarations:
          type instance BoundsOf (Maybe a) -- Defined at tyfams.hs:4:15
          type instance BoundsOf (Maybe (Maybe a)) -- Defined at tyfams.hs:5:15
    

    我不明白为什么它应该适用于 ((->) a)

    【讨论】:

    • 只有当你有无限类型时才会发生冲突(如果a ~ a->a)。正确的比较应该是具有两个类型变量的类型,例如Either,而不是Maybe。使用Either a aEither a (Either a a),只有当你有无限类型时,你才能清楚地统一Either a a ~ a
    猜你喜欢
    • 2011-04-14
    • 2012-02-13
    • 1970-01-01
    • 2021-09-17
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多