Создание класса координат в 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)
Другие вопросы по тегам