2014-04-15 17 views
10

我的一些代碼與最新版本的ghc 7.8.2斷開了。GHC 7.8中的角色破碎的代碼

我使用的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時,角色可以提高安全性,當然這非常好!

解決此問題的可能解決方案是什麼?什麼是最推薦的?

+0

根據文檔(http://www.haskell.org/ghc/docs/7.8.2/html/users_guide/roles.html),您必須更改數據類型的角色,但這可以我只相信數據類型的定義,我不確定角色如何與數據族進行交互 - 也許你可以在每個實例的基礎上定義角色 - 但我懷疑它 – user2407038

+0

但是爲了改變' MVector'我應該在'vector'庫中更改它,也許我應該向'vector'包的維護者報告。 – LambdaStaal

回答

2

這裏有一個錯誤是明智的 - FacePosU.MVector實例可能與VoxelPos的實例完全無關。有一個很好的方法來解決這個問題,但:

newtype instance U.MVector s FacePos = MV_FacePos (U.MVector s VoxelPos) 

這應該擺脫你看到的特定錯誤。

但是,我認爲你會馬上遇到另一個與角色相關的錯誤,因爲其他函數(不是basicLength,在那裏你被阻塞了)使用MVector參數的角色目前無法處理的方式。

的GHC團隊已經意識到了這個問題,並正在研究它:看https://ghc.haskell.org/trac/ghc/ticket/9112https://ghc.haskell.org/trac/ghc/ticket/9123

在此期間,我怕我唯一的建議是使用unsafeCoerce。 :(

+0

感謝您回答這個問題。你能解釋一下我們如何使用'unsafeCoerce'來解決這個問題嗎? – crockeea