箭头与应用函子完全等价吗? [英] Arrows are exactly equivalent to applicative functors?

查看:88
本文介绍了箭头与应用函子完全等价吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据着名的论文习语是不经意的,箭头是细致的,monads是混杂的,箭头的表达能力(没有任何额外的类型特效)应该在应用函子和monad之间的某个地方:monad相当于 ArrowApply Applicative 应该等同于本文所谓的静态箭头。然而,我不清楚这个静态的含义是什么限制。



围绕着三个有问题的类型类,我能够建立一个等价在应用函子和箭头之间,我在下面介绍 Monad ArrowApply 之间众所周知的等价关系。这种结构是否正确? (我已经证明了大部分箭头法在感到无聊之前)。这并不意味着箭头 Applicative 完全相同吗?

  { - #LANGUAGE TupleSections,NoImplicitPrelude# - } 
导入Prelude(($),const,uncurry)

- In红色的角落,我们有箭头,来自* - >的地方。 * - > *
导入Control.Category
导入Control.Arrow隐藏(Kleisli)

- 在蓝色角落中,我们有适用的函子和单子
- *的骄傲 - > *
import Control.Applicative
import Control.Monad

- 回想一下众所周知的结果:每个monad产生一个ArrowApply:
newtype Kleisli mab = Kleisli { runKleisli :: a - > m b}

instance(Monad m)=>类别(Kleisli m)其中
id = Kleisli返回
Kleisli g。 Kleisli f = Kleisli $ g <=< f

instance(Monad m)=> Arrow(Kleisli m)其中
arr = Kleisli。 (返回)
first(Kleisli f)= Kleisli $ \(x,y) - > liftM(,y)(f x)

instance(Monad m)=> ArrowApply(Kleisli m)其中
app = Kleisli $ \(Kleisli f,x) - > fx

- 每个箭头arr都可以变成一个应用函子
- 用于任何原点的选择o
newtype Arrplicative arr oa = Arrplicative {runArrplicative :: arr oa}

实例(Arrow arr)=> Functor(Arrlicative arr o)其中
fmap f = Arrplicative。 (arr f。)。 runArrplicative

实例(Arrow arr)=>应用(Arrlicative arr o)其中
pure = Arrplicative。 arr。 const

语法af * Arrplicative ax = Arrplicative $
arr(uncurry($))。 (af&&& ax)

- ArrowApply的变形是单子,甚至是
实例(ArrowApply arr)=> Monad(Arrlicative arr o)其中
return = pure
Arrplicative ax>> = f =
Arrlicative $(ax>>> arr(runArrplicative。f))& &安培;&安培; id>>> app

- 每个应用函数f都可以变成箭头?
newtype Applicarrow f a b = Applicarrow {runApplicarrow :: f(a - > b)}

instance(Applicative f)=>类别(Applicarrow f)其中
id = Applicarrow $纯id
申请g。 Applicarrow f = Applicarrow $(。)< $> g * f

实例(应用f)=>箭头(Applicarrow f)其中
arr = Applicarrow。纯
先(Applicarrow f)=应用$先$> f


解决方案

让我们来比较IO应用仿函数和Kleisli箭你可以有一个箭头打印一个由前一个箭头读取的值:

<$ p

$ p $ runKleisli((Kleisli $ \() - > getLine)>>> Kleisli putStrLn)()

但是你不能用适用函数来做到这一点。通过应用函子,所有效果都会在之前将函数中的函数应用于函数中的参数。函数中的函数不能使用函数参数中的值来调整它自己的效果,可以这么说。


According to the famous paper Idioms are oblivious, arrows are meticulous, monads are promiscuous, the expressive power of arrows (without any additional typeclasses) should be somewhere strictly between applicative functors and monads: monads are equivalent to ArrowApply, and Applicative should be equivalent to something the paper calls "static arrows". However, it is not clear to me what restriction this "static"-ness means.

Playing around with the three typeclasses in question, I was able to build up an equivalence between applicative functors and arrows, which I present below in the context of the well-known equivalence between Monad and ArrowApply. Is this construction correct? (I've proven most of the arrow laws before getting bored of it). Doesn't that mean that Arrow and Applicative are exactly the same?

{-# LANGUAGE TupleSections, NoImplicitPrelude #-}
import Prelude (($), const, uncurry)

-- In the red corner, we have arrows, from the land of * -> * -> *
import Control.Category
import Control.Arrow hiding (Kleisli)

-- In the blue corner, we have applicative functors and monads,
-- the pride of * -> *
import Control.Applicative
import Control.Monad

-- Recall the well-known result that every monad yields an ArrowApply:
newtype Kleisli m a b = Kleisli{ runKleisli :: a -> m b}

instance (Monad m) => Category (Kleisli m) where
    id = Kleisli return
    Kleisli g . Kleisli f = Kleisli $ g <=< f

instance (Monad m) => Arrow (Kleisli m) where
    arr = Kleisli . (return .)
    first (Kleisli f) = Kleisli $ \(x, y) -> liftM (,y) (f x)

instance (Monad m) => ArrowApply (Kleisli m) where
    app = Kleisli $ \(Kleisli f, x) -> f x

-- Every arrow arr can be turned into an applicative functor
-- for any choice of origin o
newtype Arrplicative arr o a = Arrplicative{ runArrplicative :: arr o a }

instance (Arrow arr) => Functor (Arrplicative arr o) where
    fmap f = Arrplicative . (arr f .) . runArrplicative

instance (Arrow arr) => Applicative (Arrplicative arr o) where
    pure = Arrplicative . arr . const

    Arrplicative af <*> Arrplicative ax = Arrplicative $
        arr (uncurry ($)) . (af &&& ax)

-- Arrplicatives over ArrowApply are monads, even
instance (ArrowApply arr) => Monad (Arrplicative arr o) where
    return = pure
    Arrplicative ax >>= f =
        Arrplicative $ (ax >>> arr (runArrplicative . f)) &&& id >>> app

-- Every applicative functor f can be turned into an arrow??
newtype Applicarrow f a b = Applicarrow{ runApplicarrow :: f (a -> b) }

instance (Applicative f) => Category (Applicarrow f) where
    id = Applicarrow $ pure id
    Applicarrow g . Applicarrow f = Applicarrow $ (.) <$> g <*> f

instance (Applicative f) => Arrow (Applicarrow f) where
    arr = Applicarrow . pure
    first (Applicarrow f) = Applicarrow $ first <$> f

解决方案

Let's compare the IO applicative functor with the Kleisli arrows of the IO monad.

You can have an arrow that prints a value read by a previous arrow:

runKleisli ((Kleisli $ \() -> getLine) >>> Kleisli putStrLn) ()

But you can't do that with applicative functors. With applicative functors, all the effects take place before applying the function-in-the-functor to the arguments-in-the-functor. The function-in-the-functor can't use the value inside an argument-in-the-functor to "modulate" its own effect, so to speak.

这篇关于箭头与应用函子完全等价吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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