Why can't GHC derive instances for Monoid?

我与影子孤独终老i 提交于 2019-12-10 01:10:15

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/11165316/why-cant-ghc-derive-instances-for-monoid

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