关于应用,而不是“组合",真正的应用有多少? [英] How much is applicative really about applying, rather than "combining"?

查看:27
本文介绍了关于应用,而不是“组合",真正的应用有多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于不确定性传播近似 类型,我想通过 Monad 获得 Functor 的实例.然而,这不起作用,因为我需要包含类型的向量空间结构,所以它实际上必须是类的受限版本.因为似乎仍然没有这些标准库(或者有吗?请指点我.有 rmonad,但它使用 * 而不是 Constraint 作为上下文类型,这对我来说似乎已经过时了),我写了 我自己的版本 暂时.

For an uncertainty-propagating Approximate type, I'd like to have instances for Functor through Monad. This however doesn't work because I need a vector space structure on the contained types, so it must actually be restricted versions of the classes. As there still doesn't seem to be a standard library for those (or is there? please point me. There's rmonad, but it uses * rather than Constraint as the context kind, which seems just outdated to me), I wrote my own version for the time being.

对于 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' = ...

而是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

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

is not possible because functions a->b do not have the necessary vector space structure* FScalarBasisSpace.

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

What does work, however, is to change the definition of the restricted applicative class:

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

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

and then defining <*># rather than cliftA2 as a free function

(<*>#) = cliftA2 ($)

而不是方法.没有约束,那是完全等价的(事实上,许多 Applicative 实例都是这样的),但在这种情况下它实际上更好:(<*>#) 仍然对 a->b Approximate 不能满足,但这不会伤害应用实例,我仍然可以做一些有用的东西,比如

instead of a method. Without the constraint, that's completely equivalent (in fact, many Applicative instances go this way anyway), but in this case it's actually better: (<*>#) still has the constraint on a->b which Approximate can't fulfill, but that doesn't hurt the applicative instance, and I can still do useful stuff like

ghci> cliftA2 (x y -> (x+y)/x^2) (3±0.2) (5±0.3)        :: Approximate Double 
0.8888888888888888 +/- 0.10301238090045711

我认为对于 CApplicative 的许多其他用途,情况基本上是相同的,例如 关于约束种类的原创博文.

I reckon the situation would essentially the same for many other uses of CApplicative, for instance the Set example that's already given in the original blog post on constraint kinds.

<*>liftA2 更基础吗?

同样,在不受约束的情况下,它们无论如何都是等价的.我实际上发现 liftA2 更容易理解,但在 Haskell 中,考虑传递函数容器"而不是对象容器和一些全局"操作来组合它们可能更自然.而<*>直接为μ∊ℕ诱导了所有的liftAμ,而不仅仅是liftA2;仅从 liftA2 执行此操作 真的不行.

Again, in the unconstrained case they're equivalent anyway. I actually have found liftA2 easier to understand, but in Haskell it's probably just more natural to think about passing "containers of functions" rather than containers of objects and some "global" operation to combine them. And <*> directly induces all the liftAμ for μ ∊ ℕ, not just liftA2; doing that from liftA2 only doesn't really work.

但是,这些受约束的类似乎对 liftA2 很有帮助.特别是,它允许所有 CMonadCApplicative 实例,当 <*>#not 工作> 是基本方法.而且我认为我们都同意 Applicative 应该总是比 Monad 更通用.

But then, these constrained classes seem to make quite a point for liftA2. In particular, it allows CApplicative instances for all CMonads, which does not work when <*># is the base method. And I think we all agree that Applicative should always be more general than Monad.

范畴论者对这一切有什么看法?有没有办法获得一般的 liftAμ 而无需 a->b 需要满足相关的约束?

What would the category theorists say to all of this? And is there a way to get the general liftAμ without a->b needing to fulfill the associated constraint?

*这种类型的线性函数实际上确实具有向量空间结构,但我绝对不能仅限于这些.

*Linear functions of that type actually do have the vector space structure, but I definitely can't restrict myself to those.

推荐答案

据我所知(作为一个非范畴论者),基本操作是 zip :: f a ->f b ->f (a, b)(将一对有效计算映射到产生一对的有效计算).

As I understand it (as a non---category theorist), the fundamental operation is zip :: f a -> f b -> f (a, b) (mapping a pair of effectful computations to an effectful computation resulting in a pair).

然后你可以定义

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

请参阅我发现的 Edward Yang 的帖子="http://www.haskell.org/haskellwiki/Typeclassopedia#Alternative_formulation" rel="noreferrer">通过 Typeclassopedia.

See this post by Edward Yang, which I found via the Typeclassopedia.

这篇关于关于应用,而不是“组合",真正的应用有多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆