In Ordnung, ich versuche, meinen Kopf um Typklassen zu wickeln, und so versuche ich eine Typklasse für geometrische Vektoroperationen zu definieren. Ich schaffte es, es komponentenmäßig zu funktionieren +,-,*,/;
, aber ich kämpfe mit dem Punktprodukt.Haskell Vector Typenklasse: Funktion von [a] -> [a] -> a
class GeomVector a where
(>+) :: a -> a -> a
(>-) :: a -> a -> a
(>*) :: a -> a -> a
(>/) :: a -> a -> a
(>.) :: a -> a -> Double
data Vector a = Vec [a]
deriving Show
instance (Fractional a) => GeomVector (Vector a) where
(>+) (Vec u) (Vec v) = Vec $ zipWith (+) u v
(>-) (Vec u) (Vec v) = Vec $ zipWith (-) u v
(>*) (Vec u) (Vec v) = Vec $ zipWith (*) u v
(>/) (Vec u) (Vec v) = Vec $ zipWith (/) u v
(>.) (Vec u) (Vec v) = sum $ u >* v
Offensichtlich meine Instanzdefinition für (>.) Wird nicht funktionieren, weil das Ergebnis vom Typ Fractional a
, nicht Double
.
Aber ich weiß nicht, wie dieses Verhalten von der Deklaration in der Klasse erhalten.
Was würde ich wie zu tun ist:
class GeomVector [a] where
(>.) :: [a] -> [a] -> a
Aber das ist ungültig, weil [a]
ein Typ ist und nicht eine Art Variable.
Ich wünschte, ich könnte dies ein wenig besser erklären, aber ich verstehe ehrlich gesagt nicht genug, um dies zu tun. Hoffentlich macht der Code es ein wenig offensichtlicher, mit was ich kämpfe.
Ich denke, dass Sie eine andere Typvariable benötigen, um den Typ der Skalare zu bezeichnen, d. H. 'Klasse GeomVector a s wo ... (>.) :: a -> a -> s'. – ErikR
Was Sie wollen, ist [Synonyme Synonyme] (http://www.haskell.org/haskellwiki/GHC/Type_families#An_associated_type_synonym_example) – Lambdageek
Ihre Klassendeklaration ist nicht nur wegen (>.) Ergebnis Typ fehlerhaft. Sie versuchen, ein Punktprodukt von '' u''' und '' v''' zu erzeugen, die Listen sind, keine Instanzen Ihrer Klasse. –