Подъем экземпляра класса в Haskell
-
08-07-2019 - |
Вопрос
Есть ли способ легко "поднять" экземпляр класса в Haskell?
Мне часто приходилось создавать, например, экземпляры Num для некоторых классов, которые просто "поднимают" структуру Num с помощью конструктора типов следующим образом:
data SomeType a = SomeCons a
instance (Num a)=>Num SomeCons a where
(SomeCons x) + (SomeCons y) = SomeCons (x+y)
negate (SomeCons x) = SomeCons (negate x)
-- similarly for other functions.
Есть ли способ избежать этого шаблона и "поднять" эту числовую структуру автоматически?Обычно мне приходится делать это с Show и другими классами, также когда я пытался изучить экзистенциалы, а компилятор не позволял мне использовать deriving(Show)
.
Решение
Обобщенное расширение, выводящее новый тип, - это то, что вам здесь нужно:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Main where
newtype SomeType a = SomeCons a deriving (Num, Show, Eq)
main = do
let a = SomeCons 2
b = SomeCons 3
print $ a + b
Выходной сигнал:
*Main> main
SomeCons 5
Другие советы
GHC реализует то, что вы хотите: Расширения для получения Механизм,.
Эти изменения часто показываются для будущего расширения стандартного языка (как видно на haskell 'wiki а>) р>
Чтобы включить это расширение, вы должны использовать следующую прагму и затем используйте производную в объявлении newtype, как обычно {-# GeneralizedNewtypeDeriving #-}
data SomeType a = SomeCons a deriving (Num)
Обобщенный вывод нового типа