如何使用约束构造Applicative实例(类似于使用ContT构造Monad实例)

Pet*_*lák 12 haskell type-constraints applicative category-abstractions

这个问题涉及Monad从monad中构造一个适当的实例,但仅限于某些约束 - 例如Set.诀窍在于将其包装成ContT,这会将约束推迟到包装/展开其值.

现在我想用Applicatives 做同样的事情.特别是,我有一个pure具有类型类约束的Applicative实例.如何构建有效的实例有类似的技巧吗?Applicative

(是否有"所有应用函子的母亲"就像monad一样?)

lef*_*out 5

什么可能是最一致的方式可从开始Category,它是很自然的有限制的对象:对象!

class Category k where
  type Object k :: * -> Constraint
  id :: Object k a => k a a
  (.) :: (Object k a, Object k b, Object k c)
     => k b c -> k a b -> k a c
Run Code Online (Sandbox Code Playgroud)

然后我们定义类似爱德华如何做的仿函数

class (Category r, Category t) => Functor f r t | f r -> t, f t -> r where
  fmap :: (Object r a, Object t (f a), Object r b, Object t (f b))
             => r a b -> t (f a) (f b)
Run Code Online (Sandbox Code Playgroud)

所有这些都很好地工作,并在约束类别库中实现,这对我来说很羞耻! - 仍然不在Hackage上.

Applicative不幸的是,这样做不那么简单.在数学上,这些是幺半群算,所以我们首先需要 幺半群类.categories具有该类,但它不适用于基于约束的版本,因为我们的对象总是*带有约束的任何类型.所以我所做的就是组成一个Curry,这类似于近似.

然后,我们可以做Monoidal仿函数:

class (Functor f r t, Curry r, Curry t) => Monoidal f r t where
  pure :: (Object r a, Object t (f a)) => a `t` f a
  fzipWith :: (PairObject r a b, Object r c, PairObject t (f a) (f b), Object t (f c))
              => r (a, b) c -> t (f a, f b) (f c)
Run Code Online (Sandbox Code Playgroud)

这实际上相当于Applicative我们有适当的闭合笛卡尔类别.在约束类别版本中,遗憾的是签名非常可怕:

  (<*>) :: ( Applicative f r t
           , MorphObject r a b, Object r (r a b)
           , MorphObject t (f a) (f b), Object t (t (f a) (f b)), Object t (f (r a b))
           , PairObject r (r a b) a, PairObject t (f (r a b)) (f a)
           , Object r a, Object r b, Object t (f a), Object t (f b))
       => f (r a b) `t` t (f a) (f b)
Run Code Online (Sandbox Code Playgroud)

不过,它确实有效 - 对于无约束的情况,呃!我还没有找到一种方便的方法来使用它与非平凡的约束.

但同样,Applicative相当于Monoidal,并且如在证明可以使用Set例子.


sto*_*zly 0

因为每个 Monad 都是 Functor,所以您可以使用相同的 ContT 技巧。

pure变成return

fmap f x变成x >>= (return . f)

  • 我不确定这有帮助。如果底层受限应用中没有 `&gt;&gt;=`,您就无法投影到 `ContT` 之外。 (2认同)