为什么GHC不能为Monoid派生实例? [英] Why can't GHC derive instances for Monoid?

查看:165
本文介绍了为什么GHC不能为Monoid派生实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GHC有几个语言标志,例如 DeriveFunctor DeriveDataTypeable 等,它们使得编译器能够生成派生除了Haskell 98中允许的类型类以外的其他类型的实例。对于像 Functor 之类的东西来说,这尤其有意义,其中该类的规则规定了明显的自然派生实例。



那为什么不为 Monoid ?对于任何具有单一数据构造函数的数据类型来说,似乎都是这样的:

$ $ $ $ $ $ $ $ $ data T = MkT abc ...

可以机械地产生一个 Monoid 实例(原因是伪代码):

  instance(Monoid a,Monoid b,Monoid c,...)=> Monoid T其中
mempty =
MkT mempty mempty mempty ...
mappend(MkT a1 b1 c1 ...)(MkT a2 b2 c2 ...)=
MkT( mappend a1 a2)(mappend b1 b2)(mappend c1 c2)...

我知道派生提供了这个,但我的问题具体是GHC没有这个原因。

解决方案

确实无法派生 Monoid 是一个任意的决定,但monoids也非常通用,所以通常会有许多方式使一个类型成为一个monoid。以下是一个例子:

  data T = A | B | (a,a  - > a  - > a)

m1,m2,m3,m4:C导出(Eq,Ord,Enum)

类型Mon a = :Mon T
m1 =(A,max)
m2 =(C,min)
m3 =(A,\\ xy - > Enum $(fromEnum x + fromEnum y)` 3)
m4 =(B,f4)
f4 A _ = A
f4 B x = x
f4 C _ = C
>

这显示了使 T 一个monoid(带 Mon 包含单位和二元运算)。第一个是幺半群取最大值,第二个幺半群取最小值,第三个幺半群取模3算术,第四个是幺半群用于 Ordering 类型。没有什么真正突出的作为自然的方式。


GHC has a few language flags, such as DeriveFunctor, DeriveDataTypeable etc., which enable compiler generation of derived instances for type classes other than those allowed in Haskell 98. This especially makes sense for something like Functor, where the laws of that class dictate an obvious, "natural" derived instance.

So why not for Monoid? It seems like for any data type with a single data constructor:

data T = MkT a b c ...

one could mechanically produce a Monoid instance (excuse the pseudocode):

instance (Monoid a, Monoid b, Monoid c, ...) => Monoid T where
  mempty =
    MkT mempty mempty mempty ...
  mappend (MkT a1 b1 c1 ...) (MkT a2 b2 c2 ...) =
    MkT (mappend a1 a2) (mappend b1 b2) (mappend c1 c2) ...

I'm aware that the derive package provides this, but my question specifically is whether there's a reason why GHC does not.

解决方案

It's really an arbitrary decision to not be able to derive Monoid, but monoids are also very general so there is typically many ways to make a type a monoid. Here's an example:

data T = A | B | C deriving (Eq, Ord, Enum)

type Mon a = (a, a -> a -> a)

m1, m2, m3, m4 :: Mon T
m1 = (A, max)
m2 = (C, min)
m3 = (A, \ x y -> toEnum $ (fromEnum x + fromEnum y) `rem` 3)
m4 = (B, f4)
f4 A _ = A
f4 B x = x
f4 C _ = C

This shows four reasonable ways to make T a monoid (with Mon containing the unit and the binary operation). The first is the monoid from taking the maximum, the second the monoid from taking the minimum, the third the monoid from modulo 3 arithmetic, and the fourth is the monoid used for the Ordering type. Nothing really stands out as the natural way.

这篇关于为什么GHC不能为Monoid派生实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆