繁体   English   中英

Haskell类型类的约束,用于定义组

[英]Constraints on a Haskell typeclass for the definition of a group

我想出了一个Group的类型类定义,但是我找到了一个实际上并不是一个组的反例类型。

这是类定义和一个实例,即组ℤ2:

class Group g where
  iden :: g
  op :: g -> g -> g
  inv :: g -> g

data Z2T = Z0 | Z1

instance Group Z2T where
  iden = Z0
  Z0 `op` Z0 = Z0
  Z0 `op` Z1 = Z1
  Z1 `op` Z0 = Z1
  Z1 `op` Z1 = Z0
  inv Z0 = Z1
  inv Z1 = Z0

但是, Group那些类型签名是必要的,但是对于一个真正成为一个组的类型来说还不够,这里是我编译的反例:

data NotAGroup = N0 | N1

instance Group NotAGroup where
  iden = N0
  N0 `op` N0 = N0
  N1 `op` N0 = N0
  N0 `op` N1 = N0
  N1 `op` N1 = N0
  inv N0 = N0
  inv N1 = N0

如何将类型的足够规则编码为Haskell中的Group类型类中的Group

你是对的,可以写出违反集团法的Group类型类的实例,因为实际上代码中没有任何内容实际说明它们。

对于Monad类来说,这种情况也是如此,其中monadic法则不是以任何方式编写或强制执行的。 您可以编写一个非法的Monad实例,因为您可以编写一个非法的Group实例。

这实际上是你在Haskell中可以获得的最好的,至少不会过多地增加类型签名的复杂性。 事实上,要表达类型中的组定律,您可能需要一种完全依赖类型的语言,而Haskell则不然。

在这种情况下,法律通常写在评论中,可能表示为重写规则,程序员通常具有足够的纪律来尊重它们。

您无法执行此类法律,但您可以记录这些法律。 例如, Monoid类记录了Monoid任何实例应遵守的四个定律:

-- | The class of monoids (types with an associative binary operation that
-- has an identity).  Instances should satisfy the following laws:
--
--  * @mappend mempty x = x@
--
--  * @mappend x mempty = x@
--
--  * @mappend x (mappend y z) = mappend (mappend x y) z@
--
--  * @mconcat = 'foldr' mappend mempty@

一个组只是一个具有额外逆操作的幺半群。 使您的Group类成为Monoid的子类; 那么你只需要记录你的逆操作必须遵守的附加法则。

class Monoid g => Group g where
  ginverse :: g -> g
  -- ginv must obey the following laws
  -- x `gappend` (ginverse x) == gempty
  -- (ginverse x) `gappend` x == gempty

-- g-prefixed synonym for mappend
gappend :: Group g => g -> g -> g
gappend = mappend

-- g-prefixed synonym for mempty
gempty :: Group g => g
gempty = mempty

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM