Я хотел бы определить несколько версий вещи, но с разными типами, чтобы повысить безопасность типов в моей программе. Например, у меня есть несколько типов бивариантных значений, которые я хочу быть экземплярами Num
, но все должны быть разных типов. Так что я сделал, создавая newtype с одной переменной типа и объявляя новые типы на основе этого. Тем не менее, я нахожу это немного раздражающим, что теперь мне приходится использовать оба конструктора все время. Есть ли способ обойти это?Haskell: newtype для синонимов, безопасных по типу: любой способ использования двух конструкторов?
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Bivar t = Bivar (t,t) deriving (Show, Eq)
instance (Num t) => Num (Bivar t) where
(+) (Bivar (x1,y1)) (Bivar (x2,y2)) = Bivar (x1+x2, y1+y2)
(-) (Bivar (x1,y1)) (Bivar (x2,y2)) = Bivar (x1-x2, y1-y2)
(*) (Bivar (x1,y1)) (Bivar (x2,y2)) = Bivar (x1*x2, y1*y2)
abs (Bivar (x1,y1)) = Bivar (abs x1, abs y1)
fromInteger i = Bivar (fromInteger i, fromInteger i)
signum (Bivar (x1,y1)) = Bivar (signum x1, signum y1)
newtype BivarNode = BivarNode (Bivar Int) deriving (Show, Eq, Num)
newtype BivarVal = BivarVal (Bivar Double) deriving (Show, Eq, Num)
newtype HBivarVal = HBivarVal (Bivar Double) deriving (Show, Eq, Num)
-- This is annoying:
a1 = BivarVal (Bivar (1.0, 2.0))
a2 = HBivarVal (Bivar (1.0, 2.0))
b = BivarNode (Bivar (1,2))
-- is there a way so that I can write it this way?
aa1 = BivarVal (1.0, 2.0)
aa2 = HBivarVal (1.0, 2.0)
bb = BivarNode (1,2)
спасибо!
EDIT:
Чтобы расширить на оригинальный вопрос, я хотел бы также использовать имена типов на шаблон совпадает, то вдоль линий
myFunction :: HBivarVal -> Double
myFunction (HBivarVal (Bivar (x,y))) = x
что тоже возможно?
Для вашего второго вопроса: используйте шаблоны просмотра. –
@ ThomasM.DuBuisson Спасибо, проверим его – Paul
Новинка, обертывающая пару, действительно ничего не дает вам (хотя GHC оптимизирует простую оболочку newtype, все шаблоны должны по-прежнему использовать пару), поэтому 'data Bivar t = Bivar tt' эквивалентен и немного меньше нажатий клавиш ... –