箭头与应用函子完全等价吗? [英] Arrows are exactly equivalent to applicative functors?
问题描述
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
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屋!