不是对立/对立/可分解/可判定的好例子?

时间:2019-05-14 11:39:27

标签: haskell typeclass functor contravariant

The Contravariant family of typeclasses代表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

但是,要理解这些类型类的概念并不容易。我认为,如果您能看到一些反例,将有助于更好地理解这些类型。因此,本着Good examples of Not a Functor/Functor/Applicative/Monad?的精神,我正在寻找可以满足以下要求的对比数据类型示例:

  • 不是Contravariant的类型构造函数吗?
  • Contravariant而不是Divisible的类型构造函数吗?
  • Divisible但不是Decidable的类型构造函数吗?
  • Decidable的类型构造函数吗?

2 个答案:

答案 0 :(得分:6)

(部分答案)

不矛盾

newtype F a = K (Bool -> a)

不是协变的(但是,它是协变函子)。

相反,但不可除

newtype F a = F { runF :: a -> Void }

是协变的,但不能为Divisible,否则

runF (conquer :: F ()) () :: Void

关于“可分但不可决定”的注释

对于无法确定的可除数,我没有合理的例子。我们可以观察到这样的反例必须是这样的,因为它违反了法律,而不仅是类型签名。确实,如果Divisible F成立,

instance Decidable F where
    lose _ = conquer
    choose _ _ _ = conquer

满足方法的类型签名。

在图书馆中,当Const m是一个等分体时,我们发现m是可分的。

instance Monoid m => Divisible (Const m) where
  divide _ (Const a) (Const b) = Const (mappend a b)
  conquer = Const mempty

也许这不是合法的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

答案 1 :(得分:5)

(偏导数答案?)

我相信@chi是正确的when they hypothesizeConst m不可能是所有Decidable Monoid的合法m,但我基于出于对Decidable法律的一些猜测。

the docs中,我们得到Decidable法则的诱人提示:

  

此外,我们希望获得与通常的协变选择(w.r.t Applicative)所满足的分配律相同的知识,并应在此处完全加以表述!

DecidableDivisible应该建立什么样的分配关系?好吧,Divisiblechosen,它从元素接受事物中构建了一个产品接受事物,而Decidabledivided,从元素接受事物中构建了一个求和事物。接受元素的事物。由于乘积是按总和分配的,所以也许我们寻求的法律将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

PredicateEquivalenceOp确实很满意(到目前为止,我花了时间检查了三个Decidable实例)。

现在,我相信您可以为instance Monoid m => Decidable (Const m)使用的唯一实例对mempty使用lose,对mappend使用choose;任何其他选择,则lose不再是choose的身份。这意味着上述分配法则简化为

a `mappend` (b `mappend` c) = (a `mappend` b) `mappend` (a `mappend` c)

显然是伪造的在任意Monoid中是不正确的(尽管正如Sjoerd Visscher所观察到的那样,在某些Monoid中是正确的-因此Const m可以如果Decidable是一个分布的类半身像,仍然是合法的m