Why can't GHC derive instances for Monoid?

妖精的绣舞 提交于 2019-12-05 00:00:41

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.

You could ask the same for Num and some other classes. It would be inconsequential: All other standard derivations work for data types with multiple constructors.

As a replacement, you can use newtype deriving newtype T = MkT (a,b,c) deriving Monoid.

Similar extension: you can make the empty datatype an instance of almost every type class.

The deriving clause was always ad-hoc and inconvenient part of the Haskell, because it worked only for predefined classes. Adding even more ad-hoc extensions would complicate language. Instead, GHC has recently got support for generic deriving.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!