newtype Comparison a
在Data.Functor.Contravariant
中定义。
在contravariant-1.5
中定义的此模块的版本中,Monoid
上的Contravariant
实例定义如下:
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开始)。
在基础上,Monoid
上的Comparison
实例被定义为as follows:
deriving instance Semigroup (Comparison a)
deriving instance Monoid (Comparison a)
是什么使Monoid (Comparison a)
的实例能够自动从基中派生出来?
我应该在哪里看到mempty
和mappend
的定义?
答案 0 :(得分:5)
对于newtype
,启用GeneralizedNewtypeDeriving
的实例,是使用基础类型的实例获得的。
因此,使用mempty @ a -> a -> Ordering
(同上mappend
),然后将其重新包装为mappend :: Comparison a
。
请注意,这最终涉及函数类型b -> c
和Ordering
的半组/单调实例。
答案 1 :(得分:4)
Comparison
类型只是newtype
上方的a -> a -> Ordering
。
Ordering
是Semigroup
中定义的GHC.Base
实例。
Semigroup
的另一个相关实例是:
Semigroup b => Semigroup (a -> b)
也就是说,如果a -> b
有一个Semigroup
实例,则任何函数类型b
都有一个Semigroup
实例。
您可以将a -> a -> Ordering
视为a -> (a -> Ordering)
,即以a
作为输入并返回(a -> Ordering)
作为输出的函数。由于(a -> Ordering)
是Semigroup
实例,因此a -> (a -> Ordering)
也是如此。
同一行推理适用于Monoid
。
最后,正如chi在another answer中所写,GeneralizedNewtypeDeriving
将负责其余的工作。