在GHC 7.8中具有角色的代码损坏

时间:2014-04-15 06:34:58

标签: haskell ghc

我的一些代码被最新版本的ghc 7.8.2打破了。

我使用GeneralizedNewtypeDeriving使用以下内容导出Data.Vector.Unbox的实例:

data VoxelPos     = VoxelPos
                    {-# UNPACK #-} !Int
                    {-# UNPACK #-} !Int
                    {-# UNPACK #-} !Int
                  deriving (Show, Eq, Ord)

newtype FacePos = FacePos VoxelPos deriving ( Eq, Hashable, NFData, G.Vector U.Vector, M.MVector U.MVector, U.Unbox)

其中VoxelPos使用(Int, Int, Int)手动滚动的实例:

newtype instance U.MVector s VoxelPos = MV_VoxelPos (U.MVector s (Int, Int, Int))
newtype instance U.Vector    VoxelPos = V_VoxelPos  (U.Vector    (Int, Int, Int))
instance U.Unbox VoxelPos
instance M.MVector U.MVector VoxelPos where
  basicLength (MV_VoxelPos v) ...
  ...

这与之前版本的ghc一起使用。但升级ghc后,我收到以下错误:

Could not coerce from ‘U.MVector s (Int, Int, Int)’ to ‘U.MVector
                                                              s FacePos’
      because the second type argument of ‘U.MVector’ has role Nominal,
      but the arguments ‘(Int, Int, Int)’ and ‘FacePos’ differ
      arising from the coercion of the method ‘M.basicLength’ from type
                   ‘forall s. U.MVector s VoxelPos -> Int’ to type
                   ‘forall s. U.MVector s FacePos -> Int’
    Possible fix:
      use a standalone 'deriving instance' declaration,
        so you can specify the instance context yourself
    When deriving the instance for (M.MVector U.MVector FacePos)
我认为,这是因为增加了角色。我知道角色在使用GeneralizedNewtypeDeriving时提高了安全性,这当然非常好!

有哪些解决方案可以解决这个问题?什么是最推荐的?

1 个答案:

答案 0 :(得分:2)

此处出现错误是明智的 - U.MVector的{​​{1}}实例可能与FacePos的实例完全无关。不过有一种很好的解决方法:

VoxelPos

那应该摆脱你所看到的特定错误。

但是,我认为你会立即遇到另一个与角色相关的错误,因为其他功能(不是newtype instance U.MVector s FacePos = MV_FacePos (U.MVector s VoxelPos) ,你被阻止的地方)使用basicLength参数的角色可以'目前正在处理。

GHC小组意识到了这个问题并且正在努力:请参阅https://ghc.haskell.org/trac/ghc/ticket/9112https://ghc.haskell.org/trac/ghc/ticket/9123

与此同时,我担心我唯一的建议是使用MVector。 :(