我正在查看the Alt
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)
操作,即我们假设该类是这样编写的:
<!>
我们可以这样编写一个组合器:
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
是从函子alt
到函子(f -, f -)
的自然转变。
但是,实际上f -
类型的函数[[not不可能自然转换吗?如何编写alt
的“错误”实现进行类型检查,但会被法律拒绝?
即使那样,这些法律仍然有价值。
不是“现实世界” Haskell的自然属性。
对编写非参数代码的开发人员来说,知道何时应该添加约束以与需要参数化的代码保持兼容是很有帮助的。举止不佳的例子
alt