在Haskell中键入实例

时间:2016-07-07 14:50:25

标签: haskell

回想一下,在数学中,岩浆是一个带有二元运算的集合。我在Haskell中定义了一个岩浆类型类:

class Magma a where
    multiplication :: a -> a -> a

当然,任何带有连接运算符的类型的列表都构成了一个岩浆,实际上下面的工作在Haskell中:

instance Magma [a] where
    multiplication x y = x ++ y

同样,带有加法的实数形成了一个岩浆,但下面的实例声明在Haskell中不起作用:

instance (Num a) => Magma a where
    multiplication x y = x + y

你能解释一下为什么第一个实例声明能很好地工作,而第二个带有类型约束的声明不起作用吗? (我正在使用ghc。)

1 个答案:

答案 0 :(得分:2)

您需要FlexibleInstancesUndecidableInstances语言扩展程序:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}

class Magma a where
    multiplication :: a -> a -> a

instance (Num a) => Magma a where
    multiplication x y = x + y

或者,使用新类型:

newtype Sum a = Sum { getSum :: a }

instance (Num a) => Magma (Sum a) where
    multiplication x y = Sum $ getSum x + getSum y

请参阅Edward Kmett answer why the latter is a better approach.

另请注意,您的Magma类型类与Data.Monoid有很多共同之处,特别是您添加的Num实例 Monoid instance for Sum type重叠。

您还可以在乘法中为Monoid instance for Product type中的数字类型定义实例。