申请真正适用于申请,而不是"结合"?

lef*_*out 12 haskell type-constraints category-theory applicative

对于不确定性传播Approximate类型,我想要Functor通过实例Monad.然而,这不起作用,因为我需要在包含的类型上使用向量空间结构,因此它实际上必须是类的受限版本.由于仍有似乎并不为那些标准库(或者是那里?请点我.还有rmonad,但它使用*,而不是Constraint作为上下文样,这似乎只是过时的我),我写我自己的版本的暂时的.

这一切都很容易 Functor

class CFunctor f where
  type CFunctorCtxt f a :: Constraint
  cfmap :: (CFunctorCtxt f a, CFunctorCtxt f b)  => (a -> b) -> f a -> f b

instance CFunctor Approximate where
  type CFunctorCtxt Approximate a = FScalarBasisSpace a
  f `cfmap` Approximate v us = Approximate v' us'
   where v' = f v
         us' = ...
Run Code Online (Sandbox Code Playgroud)

但是直接翻译Applicative,就像

class CFunctor f => CApplicative' f where
  type CApplicative'Ctxt f a :: Constraint
  cpure' :: (CApplicative'Ctxt f a) => a -> f a
  (#<*>#) :: ( CApplicative'Ctxt f a
             , CApplicative'Ctxt f (a->b)
             , CApplicative'Ctxt f b)        => f(a->b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

因为函数a->b没有必要的向量空间结构*是不可能的FScalarBasisSpace.

然而,有效的是改变受限制的应用类的定义:

class CFunctor f => CApplicative f where
  type CApplicativeCtxt f a :: Constraint
  cpure :: CAppFunctorCtxt f a  => a -> f a
  cliftA2 :: ( CAppFunctorCtxt f a
             , CAppFunctorCtxt f b
             , CAppFunctorCtxt f c )        => (a->b->c) -> f a -> f b -> f c
Run Code Online (Sandbox Code Playgroud)

然后定义<*>#而不是cliftA2作为自由函数

(<*>#) = cliftA2 ($)
Run Code Online (Sandbox Code Playgroud)

而不是方法.如果没有约束,这是完全等效的(事实上,很多Applicative情况下,走这条路呢),但在这种情况下,它实际上是更好的:(<*>#)仍然有约束a->bApproximate不能履行,但不伤可适用的情况下,我仍然可以做有用的东西,如

ghci> cliftA2 (\x y -> (x+y)/x^2) (3±0.2) (5±0.3)        :: Approximate Double 
0.8888888888888888 +/- 0.10301238090045711
Run Code Online (Sandbox Code Playgroud)

我认为情况对于许多其他用途基本相同,例如已经在约束种类原始博客文章中给出CApplicativeSet示例.

所以我的问题:

<*>不是更根本的liftA2

同样,在无约束的情况下,无论如何它们都是等价的.实际上我发现它liftA2更容易理解,但在Haskell中,考虑传递"函数容器"而不是对象容器和一些"全局"操作来组合它们可能更自然.并<*>直接导致所有liftA?μ εℕ,不仅仅是liftA2; 这样做liftA2只是不起作用.

但是,这些受限制的类似乎非常重要liftA2.特别地,它允许CApplicative对所有实例CMonads,这也不能在工作时<*>#是基本方法.而且我认为我们都同意Applicative应该总是比一般Monad.

类别理论家对所有这些都说了什么?有没有办法获得一般liftA?而不a->b需要满足相关的约束?


*该类型的线性函数实际上具有向量空间结构,但我绝对不能将自己局限于那些.

dav*_*420 11

据我所知(作为一个非类别的理论家),基本操作是zip :: f a -> f b -> f (a, b)(将一对有效的计算映射到一个有效的计算导致一对).

然后你可以定义

  • fx <*> fy = uncurry ($) <$> zip fx fy
  • liftA2 g fx fy = uncurry g <$> zip fx fy

请参阅Edward Yang发表的这篇文章,我通过Typeclassopedia找到了这篇文章.

  • 我相信规范定义类似于`fzip ::(fa,fb) - > f(a,b)`和`unit ::() - > f()`--ie,采用产品的幺半群结构类型并将其提升到仿函数中.但是,使用它们会非常尴尬. (8认同)