使用构造代数包定义代数模块

use*_*338 6 haskell superclass

该包装建设性代数允许定义代数的实例模块(如矢量空间,但是使用,其中一个字段是必需的)

这是我尝试定义一个模块:

{-# 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]
Run Code Online (Sandbox Code Playgroud)

它失败了:

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.
Run Code Online (Sandbox Code Playgroud)

如果我对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.
Run Code Online (Sandbox Code Playgroud)

我看这是需要的实例Ring AModule Integer A这没有意义,并在类的定义不要求:

class (CommutativeRing r, AbelianGroup m) => Module r m where
  -- | Scalar multiplication.
  (*>) :: r -> m -> m
Run Code Online (Sandbox Code Playgroud)

你能解释一下吗?

Dan*_*her 5

该软件包包含一个

instance Ring a => Group a where ...
Run Code Online (Sandbox Code Playgroud)

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

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

Module班有一个AbelianGroup上约束mparameter¹.这意味着一个Group约束.因此,对于此实例,必须查找Group实例A.编译器找到两个匹配的实例.

这是第一个报告的错误.

接下来是因为编译器试图找到一个AbelianGroup实例A.编译器在那一点上唯一知道的实例是

instance (Group a, Ring a) => AbelianGroup a
Run Code Online (Sandbox Code Playgroud)

所以它试图找到instance Ring A where ...,但当然没有一个.

instance Group A where ...你应该添加一个,而不是评论出来

instance AbelianGroup a
Run Code Online (Sandbox Code Playgroud)

(即使它是谎言,我们只是想让它在此刻编译)并且还添加OverlappingInstances
{-# LANGUAGE #-}编译指示中.

使用时OverlappingInstances,会选择最具体的匹配实例,因此它可以满足您的需求.

¹顺便说一下,除非订单在列表中无关紧要,否则您A不是一个实例,AbelianGroup并且理所当然也不可能[(Integer,String)].