Ich habe ein Dutzend solcher Newtypes:
newtype MyBool = MyBool Bool
newtype MyInt = MyInt Int
Ich möchte vorhandene Instanzen wiederverwenden:
instance MArray IOUArray Int IO where ...
instance MArray (STUArray s) Int (ST s) where ...
Das Implementieren dieser Instanzen und des gesamten Boilerplate-Codes ist das Letzte, was ich möchte.
Ich habe etwas gefunden, das dem sehr nahe kommt, was ich erreichen möchte:
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
deriving instance MArray IOUArray MyInt IO
deriving instance MArray (STUArray s) MyInt (ST s)
Es schlägt jedoch fehl mit:
Can't make a derived instance of ‘MArray IOUArray MyInt IO’
(even with cunning GeneralizedNewtypeDeriving):
cannot eta-reduce the representation type enough
In the stand-alone deriving instance for ‘MArray IOUArray MyInt IO’
Wie funktioniert das?
Wenn nicht möglich, was ist der am wenigsten schmerzhafte Weg, um diese Instanzen zu erhalten?
type role IOUArray nominal nominal
sodass wir nicht von Array-of-Int zu Array-of-Myint zwingen können. (Ich frage mich, warum wir solche Rollen haben.)Storable
Instanz für ihre Darstellungen ohne Box verwenden konnten (z. B. die Verwendung einerInt
Ganzzahl , die kürzer als eine Ganzzahl ist, um sie ohne Box zu speichernnewtype Age = Age Int
).Antworten:
Aus der Dokumentation :
Da der letzte Klassenparameter in Ihrem Fall nicht
Int
/MyInt
, sondernIO
/ istST s
, haben SieGeneralizedNewtypeDeriving
leider kein Glück damit .quelle
Okay, Sie stecken hier irgendwie fest, weil einige Designentscheidungen im
array
Paket es schwierig gemacht haben, aber hier ist ein Ansatz, der helfen kann, die Boilerplate zu minimieren.Sie können eine Typfamilie einführen, um Ihre neuen Typen der zugrunde liegenden Darstellung zuzuordnen:
und dann neue Typvarianten der Typen
IOUArray
undSTUArray
Array einführen :und verwenden Sie DIESE , um geeignete
MArray
Instanzen für Ihre neuen Typen zu erhalten:Nun sollten Sie in der Lage sein zu verwenden
NTIOUArray
undNTSTUArray
anstelle der üblichenIOUArray
undSTUArray
für beide eingebauten und Ihre newtype Elementtypen:Alle
IArray
Instanzen können mithilfe dervia
Ableitung automatisch generiert werden (was funktioniert, da der Elementtyp das letzte Argument für dieIArray
Einschränkung ist):oder Sie könnten die gleiche Technik wie oben mit einem
NTIArray
Newtype verwenden.Einige Beispielcodes:
quelle
Okay, you're kind of stuck here because some design choices in the array package have made it difficult.
? Ich verstehe nicht, was beim Ableiten schief geht und was der folgende Fehler bedeutet. `Eine abgeleitete Instanz von 'MArray IOUArray MyInt IO' kann nicht erstellt werden (auch bei gerissenem GeneralizedNewtypeDeriving): Der Darstellungstyp kann nicht ausreichend reduziert werden. In der eigenständigen Ableitungsinstanz für 'MArray IOUArray MyInt IO'`