2016-12-05 7 views
3

Это работало отлично в GHC 7.8.4, но терпит неудачу в 7.10.3:Использование NewType в Data.Array.Unboxed с GHC 7.10

{-# LANGUAGE DeriveGeneric    #-} 
{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

module Foo where 

import qualified Data.Array.Unboxed  as A 
import   GHC.Generics    (Generic) 

newtype Elt = Elt Int deriving (Eq, Ord, Show, Num, Integral, Real, Enum, A.IArray A.UArray, Generic) 
type MyArr = A.UArray Int Elt 

с большим количеством сообщений, как

/tmp/my.hs:9:75: 
    Couldn't match type ‘Int’ with ‘Elt’ 
    arising from the coercion of the method ‘Data.Array.Base.numElements’ 
     from type ‘forall i. A.Ix i => A.UArray i Int -> Int’ 
     to type ‘forall i. A.Ix i => A.UArray i Elt -> Int’ 
    Relevant role signatures: 
     type role A.Ix nominal 
     type role A.UArray nominal nominal 
    When deriving the instance for (A.IArray A.UArray Elt) 

Хотя примечания к выпуску для 7.10 не упоминают об этом, я вижу, https://ghc.haskell.org/trac/ghc/ticket/9220#comment:11 допускает его нарушение. Но каково решение - действительно ли мне нужно создать оболочку newtype для MyArr с вспомогательными функциями для каждого использования?

+0

Интересно. Может быть, 'UArray' перешел от представительской к номинальной роли для элемента? Интересно, почему. – chi

+1

Да, похоже, что вы будете (другой аргумент для 'vector' - получение' UnBox' экземпляров намного проще). Даже если вы хотите 'unsafeCoerce' свой путь через экземпляр« IArray UArray Elt », вы не можете, так как методы, которые вам нужно реализовать, не экспортируются. Хотя я понимаю, почему мы не должны здесь GND, тот факт, что мы не можем отписать наш экземпляр 'IArray', делает меня немного недовольным ... – Alec

+1

Вы можете импортировать методы из' Data.Array.Base'. –

ответ

1

Вам не нужно создавать обертку для MyArr, но вам придется вручную выписать экземпляр, который вы ранее получили. Немного решения грубой силы - unsafeCoerce ваш путь через экземпляр IArray вручную (причина, по которой вы не можете coerce - это то же, что вы не можете получить).

{-# LANGUAGE InstanceSigs, ScopedTypeVariables, MultiParamTypeClasses #-} 

import Data.Array.Base 
import Data.Array.IArray 
import Data.Array.Unboxed 
import Unsafe.Coerce 

instance IArray UArray Elt where 
    bounds :: forall i. Ix i => UArray i Elt -> (i, i) 
    bounds arr = bounds (unsafeCoerce arr :: UArray i Int)                                           

    numElements :: forall i. Ix i => UArray i Elt -> Int 
    numElements arr = numElements (unsafeCoerce arr :: UArray i Int) 

    unsafeArray :: forall i. Ix i => (i,i) -> [(Int, Elt)] -> UArray i Elt 
    unsafeArray lu ies = unsafeCoerce (unsafeArray lu [ (i,e) | (i,Elt e) <- ies ] :: UArray i Int) :: UArray i Elt 

    unsafeAt :: forall i. Ix i => UArray i Elt -> Int -> Elt 
    unsafeAt arr ix = Elt (unsafeAt (unsafeCoerce arr :: UArray i Int) ix) 

 Смежные вопросы

  • Нет связанных вопросов^_^