Создание класса координат в Haskell
Я пытаюсь добавить два полиморфных кортежа вместе попарно. (Типы первого элемента в одном кортеже должны быть такими же, как первый во втором и аналогично для второго элемента). Вот мой код:
module Main where
class Coordinate a where
createCoordinate :: a
getFirst :: (a,b) -> a
getSecond :: (a,b) -> b
addCoordinates :: (a,b) -> (a,b) -> (a,b)
instance Coordinate () where
createCoordinate = ()
getFirst (a,b) = a
getSecond (a,b) = b
addCoordinates a b = (getFirst a + getFirst b, getSecond a + getSecond b)
Итак, проблема в моей функции addCoordinates. Мне было интересно, если кто-нибудь может предложить мне какую-либо помощь в реализации этой функции. Спасибо!:)
2 ответа
Вы, вероятно, хотите тип данных, а не класс:
data Coordinate a b = Coordinate { getFirst :: a, getSecond :: b }
deriving (Eq, Ord, Show)
Тогда ваши функции станут:
createCoordinate :: a -> b -> Coordinate a b
createCoordinate a b = Coordinate a b
addCoordinates :: (Num a, Num b) => Coordinate a b -> Coordinate a b -> Coordinate a b
addCoordinates (Coordinate a1 b1) (Coordinate a2 b2) = Coordinate (a1+a2) (b1+b2)
Обратите внимание, что a
а также b
может быть любого типа, но addCoordinates
работает только если они являются экземплярами Num
потому что мы хотим применить +
им. Вам не нужен класс типов для определения Coordinate
,
Класс типов позволит вам определять вещи, которые могут быть инициализированы значениями по умолчанию, например:
class DefaultInitializable a where
defaultInit :: a
Затем мы можем сделать Int
Экземпляр этого класса:
instance DefaultInitializable Int where
defaultInit = 0
И мы можем сделать Coordinate
экземпляр, если его параметры также являются экземплярами:
instance (DefaultInitializable a, DefaultInitializable b) => DefaultInitializable (Coordinate a b) where
defaultInit = Coordinate default default
Я чувствую, что это может быть решением того, что я хотел
module Main where
class Coordinate c where
createCoordinate :: x -> y -> c x y
getFirst :: c x y -> x
getSecond :: c x y -> y
addCoordinates :: (Num x) => (Num y) => c x y -> c x y -> c x y
instance Coordinate (,) where
createCoordinate a b = (a,b)
getFirst (a,_) = a
getSecond (_,b) = b
addCoordinates a b = (getFirst a + getFirst b, getSecond a + getSecond b)