Хорошо, я пытаюсь разобраться с классами типов, поэтому я пытаюсь определить класс типов для операций с геометрическими векторами. Мне удалось заставить его работать по компонентам +,-,*,/;
, но я борюсь с точечным продуктом.
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
Очевидно, что мое определение экземпляра для (>.) не будет работать, потому что результат имеет тип Fractional a
, а не Double
.
Но я не знаю, как получить такое поведение из объявления в классе.
Я хочу сделать следующее:
class GeomVector [a] where
(>.) :: [a] -> [a] -> a
Но это неверно, потому что [a]
— это тип, а не переменная типа.
Я хотел бы объяснить это немного лучше, но я, честно говоря, недостаточно понимаю, чтобы сделать это. Надеюсь, код сделает более очевидным то, с чем я борюсь.
class GeomVector a s where ... (>.) :: a -> a -> s
. - person ErikR   schedule 05.12.2012u
иv
, которые являются списками, а не экземплярами вашего класса. - person Dmitry Dzhus   schedule 05.12.2012data Scalar a
)? - person Dmitry Dzhus   schedule 05.12.2012Scalar a
должен быть каким-то существующим типом (например, дляinstance GeomVector [a]
это должен бытьa
), а не совершенно новым типом данных. - person Lambdageek   schedule 05.12.2012