在Data.Functor.Contravariant中定义了newtype Comparison a。
在contravariant-1.5中定义的此模块版本中,Contravariant上的Monoid实例定义如下:
instance Monoid (Comparison a) where
mempty = Comparison (\_ _ -> EQ)
mappend (Comparison p) (Comparison q) = Comparison $ mappend p q在base中也定义了Data.Functor.Contravariant (显然是从GHC8.6.1开始)。在base中,Comparison上的Monoid实例定义为as follows
deriving instance Semigroup (Comparison a)
deriving instance Monoid (Comparison a)什么使Monoid (Comparison a)实例能够自动派生到base?
我应该在哪里找到它的mempty和mappend的定义?
发布于 2019-01-03 18:05:25
对于启用了GeneralizedNewtypeDeriving的newtype,实例是使用基础类型的实例获取的。
因此,使用了mempty @ a -> a -> Ordering (mappend的情况也是如此),然后重新包装为mappend :: Comparison a。
请注意,这最终涉及到函数类型b -> c和Ordering的半群/么半群实例。
发布于 2019-01-03 18:07:46
Comparison类型只是a -> a -> Ordering上的newtype。
我认为Ordering是在GHC.Base中定义的Semigroup实例。
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会处理剩下的事情。
https://stackoverflow.com/questions/54019789
复制相似问题