Comparison 上的 Monoid 实例在哪里定义?

Where is the Monoid instance on Comparison defined?

newtype Comparison a 定义在 Data.Functor.Contravariant.

contravariant-1.5中定义的这个模块的版本中,Contravariant上的Monoid实例定义如下:

instance Monoid (Comparison a) where
  mempty = Comparison (\_ _ -> EQ)
  mappend (Comparison p) (Comparison q) = Comparison $ mappend p q

Data.Functor.Contravariant 也在 base 中定义(显然是从 GHC 8.6.1 开始)。 在 base 中,Comparison 上的 Monoid 实例定义为 as follows:

deriving instance Semigroup (Comparison a)
deriving instance Monoid (Comparison a)

是什么使得 Monoid (Comparison a) 的实例能够在 base 中自动派生?

我应该在哪里查看 memptymappend 的定义?

newtypes,启用GeneralizedNewtypeDeriving,实例是使用基础类型的实例获得的。

因此,使用 mempty @ a -> a -> Orderingmappend 也是如此),然后重新包装为 mappend :: Comparison a

请注意,这最终涉及函数类型 b -> c 的 semigroup/monoid 实例和 Ordering 的实例。

Comparison 类型只是 a -> a -> Orderingnewtype

Ordering 是一个 Semigroup 实例,我认为 GHC.Base.

Semigroup 的另一个相关实例是:

Semigroup b => Semigroup (a -> b)

也就是说,任何函数类型 a -> b 都有一个 Semigroup 实例,如果 b 有一个 Semigroup 实例。

您可以将 a -> a -> Ordering 视为 a -> (a -> Ordering),即以 a 作为输入,并以 returns (a -> Ordering) 作为输出的函数。由于 (a -> Ordering) 是一个 Semigroup 实例,因此 a -> (a -> Ordering) 也是。

同样的推理也适用于 Monoid

最后,正如 chi 在 中所写,GeneralizedNewtypeDeriving 负责剩下的工作。