简体   繁体   中英

Broken code with roles in GHC 7.8

Some of my code is broken with the newest version of ghc 7.8.2.

I'm using GeneralizedNewtypeDeriving to deriving instances of Data.Vector.Unbox using the following:

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)

where VoxelPos have manual rolled instances using (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) ...
  ...

and this was working with the previous versions of ghc. But after upgrading ghc, I get the following error:

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)

which, I think, is because of addition of roles. I know that roles improves safety when using GeneralizedNewtypeDeriving which is, of course, really good!

What are the possible solutions to solve this? And what is the most recommended one?

Having an error here is sensible -- it's possible that the U.MVector instance for FacePos is utterly unrelated to the instance for VoxelPos . There's a nice way to fix this, though:

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

That should get rid of the particular error you're seeing.

However, I think you'll hit another role-related error right away, because other functions (not basicLength , where you're snagged) use the MVector parameters in a way roles can't currently deal with.

The GHC team is aware of this problem and is working on it: see https://ghc.haskell.org/trac/ghc/ticket/9112 and https://ghc.haskell.org/trac/ghc/ticket/9123

In the meantime, I'm afraid my only suggestion is to use unsafeCoerce . :(

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM