我的一些代码被最新版本的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)
Run Code Online (Sandbox Code Playgroud)
哪里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) ...
...
Run Code Online (Sandbox Code Playgroud)
这与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)
Run Code Online (Sandbox Code Playgroud)
我认为,这是因为增加了角色.我知道角色在使用时提高了安全性GeneralizedNewtypeDeriving,当然,这非常好!
有哪些解决方案可以解决这个问题?什么是最值得推荐的呢?
小智 2
U.MVector这里出现错误是明智的—— for 的实例可能FacePos与 的实例完全无关VoxelPos。不过,有一个很好的方法可以解决这个问题:
newtype instance U.MVector s FacePos = MV_FacePos (U.MVector s VoxelPos)
Run Code Online (Sandbox Code Playgroud)
这应该可以消除您所看到的特定错误。
但是,我认为您会立即遇到另一个与角色相关的错误,因为其他函数(不是basicLength您遇到的问题)MVector以角色当前无法处理的方式使用参数。
GHC 团队已经意识到这个问题并正在努力解决:请参阅https://ghc.haskell.org/trac/ghc/ticket/9112和https://ghc.haskell.org/trac/ghc/ticket/9123
与此同时,恐怕我唯一的建议是使用unsafeCoerce. :(