回想一下,在数学中,岩浆是一个对其进行二元运算的集合。我正在 Haskell 中定义一个 magma 类型类:
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。)
最佳答案
您将需要FlexibleInstances
和 UndecidableInstances
语言扩展:
{-# 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 中所示。 。
关于haskell - Haskell 中的类型实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38248626/