2014-04-15 12 views
10

Niektóre z moich kodów są zepsute najnowszą wersją ghc 7.8.2.Złamany kod z rolami w GHC 7.8

Używam GeneralizedNewtypeDeriving do wynikających wystąpień Data.Vector.Unbox przy użyciu następujących:

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) 

gdzie VoxelPos mieć podręcznik walcowane przypadki korzystania (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) ... 
    ... 

i to pracowała z poprzednimi wersjami ghc. Ale po aktualizacji ghc pojawia się następujący błąd:

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) 

co, jak sądzę, jest spowodowane dodaniem ról. Wiem, że role zwiększają bezpieczeństwo podczas korzystania z GeneralizedNewtypeDeriving, co oczywiście jest naprawdę dobre!

Jakie są możliwe rozwiązania tego rozwiązania? A jaki jest najbardziej zalecany?

+0

Zgodnie z dokumentami (http://www.haskell.org/ghc/docs/7.8.2/html/users_guide/roles.html), musisz zmienić rolę typu danych, ale może to tylko w definicji typu danych, jak sądzę, nie jestem pewien, jak role wchodzą w interakcje z rodzinami danych - może możesz definiować role na podstawie poszczególnych instancji - ale wątpię w to. – user2407038

+0

Ale żeby zmienić rolę ". MVector "Powinienem to zmienić w bibliotece' vector' Może powinienem zgłosić to do opiekuna pakietu 'vector' – LambdaStaal

Odpowiedz

2

Wystąpienie tutaj błędu jest sensowne - możliwe, że instancja U.MVector dla FacePos jest całkowicie niezwiązana z instancją dla VoxelPos. Istnieje jednak dobry sposób, aby to naprawić:

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

To powinno pozbyć się konkretnego błędu, który widzisz.

Jednak myślę, że od razu trafisz na inny błąd związany z rolą, ponieważ inne funkcje (a nie basicLength, w których zostałeś złapany) używają parametrów MVector w sposób, w jaki obecnie nie radzą sobie z rolami.

Zespół GHC jest świadom tego problemu i pracuje nad nim: patrz https://ghc.haskell.org/trac/ghc/ticket/9112 i https://ghc.haskell.org/trac/ghc/ticket/9123

W międzyczasie, obawiam się tylko moja sugestia jest użycie unsafeCoerce. :(

+0

Dziękuję za odpowiedź: czy mógłbyś wyjaśnić, w jaki sposób możemy użyć' unsafeCoerce' aby rozwiązać ten problem? – crockeea

Powiązane problemy