Эксклюзивный экземпляр класса Haskell
Есть ли способ "поднять" экземпляр класса в 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.
Есть ли способ избежать этого шаблона и "поднять" эту структуру Num автоматически? Обычно я должен делать это с помощью Show и других классов, когда я пытался изучить существующие имена, и компилятор не разрешил мне использовать deriving(Show)
.
Ответы
Ответ 1
Обобщенное расширение, генерируемое новым типом, - это то, что вы хотите здесь:
{-# 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
Ответ 2
GHC реализует то, что вы хотите: Расширения к производному mecanism.
Эти изменения часто показываются для дальнейшего расширения стандартного языка (см. haskell 'wiki)
Чтобы включить это расширение, вы должны использовать следующую pragma
{-# GeneralizedNewtypeDeriving #-}
а затем используйте вывод вашего объявления newtype, как обычно
data SomeType a = SomeCons a deriving (Num)
Ответ 3
GeneralizedNewtypeDeriving