我正在查看typeclass的法律,Alt
如下所示:
class Functor f => Alt f
where
(<!>) :: f a -> f a -> f a
其中一项法律是这样的:
<$> left-distributes over <!>: f <$> (a <!> b) = (f <$> a) <!> (f <$> b)
更详细地说,这是:
fmap f $ (<!>) a b = (<!>) (fmap f a) (fmap f b)
假设我们 uncurry<!>
操作,即我们假设类是这样写的:
class Functor f => Alt f
where
alt :: (f a, f a) -> f a
我们可以这样写一个组合器:
mapBoth :: Functor f => (a -> b) -> (f a, f a) -> (f b, f b)
mapBoth f = bimap (fmap f) (fmap f)
这表示type Pair a = (a, a)
函子与给定函子的组合f
。所以它本身就是函子的态射映射。
有问题的法律现在可以这样写(不改变其含义):
fmap f . alt = alt . mapBoth f
请注意,就像在法律的原始陈述中一样,mapBoth f
它只是适用fmap f
于 的两个论点。alt
This is akin to demanding that alt
is a natural transformation from the functor (f -, f -)
to the functor f -
.
However, isn't it actually impossible for a function of alt
's type not to be a natural transformation? How would one write a "bad" implementation of alt
that that typechecks, but would be rejected by the law?