Dies ist ein Follow-up zu this question, aber das Problem ist etwas anders in Anwendung und Grund, so entschied ich mich, eine neue Frage zu stellen.Simplfying Art durch Fixieren Parameter
Betrachten diese Definitionen (edit: dieser Teil einer externen Bibliothek sind):
class (Num a, Cast a b, Cast b a, Storable b, Code b) => Elem a b | a -> b where
data Matrix a b where
Matrix :: Elem a b => !Int -> !Int -> !(Vector b) -> Matrix a b
instance Elem Float CFloat where
instance Elem Double CDouble where
instance Elem (Complex Float) (CComplex CFloat) where
instance Elem (Complex Double) (CComplex CDouble) where
In anderen Worten, eine Gleitkomma-Matrix mit darunter liegenden C-Typ "fixed" durch die funktionale Abhängigkeit Elem.
Jetzt, um einige Instanzen für bestimmte Container spezifische Klassen zu implementieren (in meinem speziellen Fall für die Lookup Klasse, aber Ixed von Linse könnte ein anderer Kandidat sein) Ich brauche einen Matrix-Typ mit einem Typ Parameter.
Ich habe versucht, die folgenden:
type family CType a where
CType Double = CDouble
CType Float = CFloat
CType (Complex Double) = (CComplex CDouble)
CType (Complex Float) = (CComplex CFloat)
newtype MatX a = MatX { getMatX :: Matrix a (CType a) }
Bitte beachte, dass ich nicht einfach erlaubt bin, das „b“ Art in der newtype Erklärung wegzulassen, so dass die Art Synonym als Mittel dient dazu, die interne Art zu beheben.
jedoch alle Funktionen auf dem Matrix-Typ haben Typen wie
(Elem a b) => Matrix a b -> some -> other -> params -> result
Als Beispiel wird die unsafeCoeff Funktion wie folgt aussieht:
unsafeCoeff :: Elem a b => Int -> Int -> Matrix a b -> a
unsafeCoeff row col (Matrix rows _ vals) = cast $ Data.Vector.Storable.unsafeIndex vals $ col * rows + row
mit dieser Art mATX wie zum Beispiel:
instance Lookup MatX where
lookup (i,j) m = Just $ unsafeCoeff i j (getMatX m)
gibt mir den Fehler "Keine Instanz für (Elem a (CType a))". Da ich diese Instanzen nicht angeben darf (da Typ-Synonyme in Instanz-Deklarationen nicht erlaubt sind) bin ich an dieser Stelle irgendwie festgefahren. Ich sehe, warum der Compiler nicht annehmen kann, dass Elem a (CType a) tatsächlich gegeben ist, aber ich weiß nicht, wie ich diese Beziehung spezifizieren soll.
Bonus:
Ich habe auch versucht, nur dies zu tun:
instance Lookup (Matrix a) where
lookup (i,j) m = Just $ unsafeCoeff i j m :: Maybe a
Aber dann "b" ist der Elementtyp des Behälters und die Lookup-Funktion muss zurückkehren (die nicht näher bezeichnet) b.
Edit: Die Vollständigkeit halber die Definition Lookup aus dem obigen Link:
type family Key f
class Lookup f where
lookup :: Key f -> f a -> Maybe a
Was ist die Definition der Klasse 'Lookup'? –
@ReidBarton: Ich habe am Ende der Frage hinzugefügt. –
Wenn eine 'Matrix' eine 'Elem a b'-Bedingung enthält, warum benötigen die Operationen in' Matrix' auch einen 'Elem a b' Kontext? –