She*_*rsh 9 haskell functor typeclass contravariant
该Contravariant
类型类的家庭代表在Haskell的生态标准和基本抽象:
class Contravariant f where
contramap :: (a -> b) -> f b -> f a
class Contravariant f => Divisible f where
conquer :: f a
divide :: (a -> (b, c)) -> f b -> f c -> f a
class Divisible f => Decidable f where
lose :: (a -> Void) -> f a
choose :: (a -> Either b c) -> f b -> f c -> f a
Run Code Online (Sandbox Code Playgroud)
但是,要理解这些类型类的概念并不容易。我认为,如果可以看到一些反例,将有助于更好地理解这些类型。因此,本着“ 不是函子/函子/应用/单子”的榜样精神?,我正在寻找满足以下要求的对比数据类型示例:
Contravariant
?Contravariant
,但不是Divisible
?Divisible
,但不是Decidable
?Decidable
?(部分答案)
newtype F a = K (Bool -> a)
Run Code Online (Sandbox Code Playgroud)
不是协变的(但是,它是协变函子)。
newtype F a = F { runF :: a -> Void }
Run Code Online (Sandbox Code Playgroud)
是反变的,但不能这样Divisible
,否则
runF (conquer :: F ()) () :: Void
Run Code Online (Sandbox Code Playgroud)
对于没有确定性的可除数,我没有合理的例子。我们可以观察到这样的反例必须是这样的,因为它违反了法律,而不仅是类型签名。确实,如果Divisible F
成立,
instance Decidable F where
lose _ = conquer
choose _ _ _ = conquer
Run Code Online (Sandbox Code Playgroud)
满足方法的类型签名。
在库中,我们发现Const m
一个何时可m
分为等分线。
instance Monoid m => Divisible (Const m) where
divide _ (Const a) (Const b) = Const (mappend a b)
conquer = Const mempty
Run Code Online (Sandbox Code Playgroud)
也许这不能合法Decidable
吗?(我不确定,这似乎满足Decidable
法律要求,但是Decidable (Const m)
库中没有实例。)
取自图书馆:
newtype Predicate a = Predicate (a -> Bool)
instance Divisible Predicate where
divide f (Predicate g) (Predicate h) = Predicate $ \a -> case f a of
(b, c) -> g b && h c
conquer = Predicate $ const True
instance Decidable Predicate where
lose f = Predicate $ \a -> absurd (f a)
choose f (Predicate g) (Predicate h) = Predicate $ either g h . f
Run Code Online (Sandbox Code Playgroud)
(偏导数答案?)
我相信@chi是正确的,当他们推测这Const m
可能不是一个合法Decidable
所有的Monoid
小号m
,但我立足的关于有人猜测关Decidable
法律。
在docs中,我们得到了关于Decidable
法律的诱人提示:
此外,我们期望与通常的协变选择wrt Applicative所满足的分布律相同,应在此处完全制定并添加!
什么样的分配关系,应该Decidable
和Divisible
与对方吗?好,Divisible
has chosen
,从元素接受的事物中构建出产品接受事物,而Decidable
has divided
,从元素接受的事物中构建出总和接受事物。由于产品分布于资金,也许是法律,我们正在寻求涉及f (a, Either b c)
到f (Either (a, b) (a, c))
,它的值可以通过构建a `divided` (b `chosen` c)
和(a `divided` b) `chosen` (a `divided` c)
分别。
因此,我假设缺失的Decidable
定律与
a `divided` (b `chosen` c) = contramap f ((a `divided` b) `chosen` (a `divided` c))
where f (x, y) = bimap ((,) x) ((,) x) y
Run Code Online (Sandbox Code Playgroud)
对Predicate
,Equivalence
和确实满意Op
(Decidable
到目前为止,我花了时间检查了三个实例)。
现在,我相信您可以拥有for 和for instance Monoid m => Decidable (Const m)
用途的唯一实例;任何其他选择,则不再是。这意味着上述分配法则简化为mempty
lose
mappend
choose
lose
choose
a `mappend` (b `mappend` c) = (a `mappend` b) `mappend` (a `mappend` c)
Run Code Online (Sandbox Code Playgroud)
这显然是伪造的,在任意方面是不正确的Monoid
(尽管正如Sjoerd Visscher所观察到的那样,在某些情况下是正确Monoid
的-因此Const m
,Decidable
如果它m
是一个分布的半定式仍然是合法的)。