haskell - 使用 constructive-algebra 包定义代数模块

标签 haskell superclass

构造代数允许您定义代数模块的实例(类似于向量空间,但使用 em> 其中需要字段)

这是我定义模块的尝试:

{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances #-}
module A where
import Algebra.Structures.Module
import Algebra.Structures.CommutativeRing
import Algebra.Structures.Group

newtype A = A [(Integer,String)]

instance Group A where
    (A a) <+> (A b) = A $ a ++ b
    zero = A []
    neg (A a) = A $ [((-k),c) | (k,c) <-  a]


instance Module Integer A where
    r *> (A as) = A [(r <*> k,c) | (k,c) <- as]

它失败了:

A.hs:15:10:
    Overlapping instances for Group A
      arising from the superclasses of an instance declaration
    Matching instances:
      instance Ring a => Group a -- Defined in Algebra.Structures.Group
      instance Group A -- Defined at A.hs:9:10-16
    In the instance declaration for `Module Integer A'

A.hs:15:10:
    No instance for (Ring A)
      arising from the superclasses of an instance declaration
    Possible fix: add an instance declaration for (Ring A)
    In the instance declaration for `Module Integer A'
Failed, modules loaded: none.

如果我注释掉 Group 实例,则:

A.hs:16:10:
    No instance for (Ring A)
      arising from the superclasses of an instance declaration
    Possible fix: add an instance declaration for (Ring A)
    In the instance declaration for `Module Integer A'
Failed, modules loaded: none.

我将此理解为需要 Ring A 实例具有 Module Integer A,这没有意义,并且在类定义中不是必需的:

class (CommutativeRing r, AbelianGroup m) => Module r m where
  -- | Scalar multiplication.
  (*>) :: r -> m -> m

你能解释一下吗?

最佳答案

包装内含

instance Ring a => Group a where ...

实例头a匹配每个类型表达式,因此任何具有任何其他类型表达式的实例都会重叠。如果这样的实例实际在某处使用,那么这种重叠只会导致错误。在您的模块中,您使用

中的实例
instance Module Integer A where
    r *> (A as) = A [(r <*> k,c) | (k,c) <- as]

Module 类对 m 参数有一个 AbelianGroup 约束。这意味着Group 约束。因此,对于此实例,必须查找 AGroup 实例。编译器找到两个匹配的实例。

这是第一个报告的错误。

下一个是因为编译器尝试为 A 查找 AbelianGroup 实例。编译器此时知道的唯一实例是

instance (Group a, Ring a) => AbelianGroup a

因此它尝试查找实例 Ring A 所在位置...,但当然没有。

您应该添加一个

,而不是注释掉实例组 A where ...
instance AbelianGroup a

(即使这是一个谎言,我们现在只想让它编译)并将 OverlappingInstances 添加到
{-# LANGUAGE #-} 编译指示。

使用OverlappingInstances,会选择最具体的匹配实例,因此它会执行您想要的操作。

顺便说一句,您的 A 不是 AbelianGroup 的实例,并且理所当然地不可能是,除非 [(Integer, String)] 列表。

关于haskell - 使用 constructive-algebra 包定义代数模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10536990/

相关文章:

Haskell:类型类问题

haskell - Haskell 中的父类(super class)型

用于登录的 Java 父类(super class)用户

java - 构造函数 this() 不必要吗?

oop - 使用抽象父类(super class)的好的设计模式是什么?

java - 当类是字节数组形式时确定类的父类(super class)?

haskell - 共享 IORef 时,只要我使用atomicModifyIORef 写入,使用 readIORef 读取是否安全?

haskell - "symmetric"函数的模式

haskell - Haskell 的 SDL 库中的操纵杆事件处理

java - java中的 super 构造函数