gpt4 book ai didi

haskell - 箭头完全等同于应用仿函数?

转载 作者:行者123 更新时间:2023-12-03 07:56:51 25 4
gpt4 key购买 nike

根据著名论文Idioms are oblivious, arrows are meticulous, monads are promiscuous ,箭头的表达能力(没有任何额外的类型类)应该严格介于应用仿函数和 monad 之间:monad 等价于 ArrowApply , 和 Applicative应该等同于论文所说的“静态箭头”。但是,我不清楚这种“静态”意味着什么限制。

玩弄有问题的三个类型类,我能够建立应用仿函数和箭头之间的等价性,我将在下面介绍 Monad 之间众所周知的等价性。和 ArrowApply .这种结构正确吗? (在厌倦之前,我已经证明了 arrow laws 的大部分内容)。这不是说ArrowApplicative完全一样吗?

{-# 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

最佳答案

每个应用程序都会产生一个箭头,每个箭头都会产生一个应用程序,但它们并不等价。如果你有箭头 arr和态射 arr a b这并不意味着您可以生成态射 arr o (a \to b)复制其功能。因此,如果您通过应用程序往返,您将失去一些功能。

应用程序是单曲面仿函数。箭头是profunctors,也是类别,或者等效地,在profunctors类别中的幺半群。这两个概念之间没有自然的联系。如果你能原谅我的轻率:在 Hask 中,箭头中的 pro-functor 的 functor 部分是一个幺半群 functor,但这种构造必然会忘记“pro”部分。

当您从箭头转到应用程序时,您会忽略箭头中接受输入的部分,而只使用处理输出的部分。许多有趣的箭头以一种或另一种方式使用输入部分,因此通过将它们变成应用程序,您放弃了有用的东西。

也就是说,在实践中,我发现可以使用更好的抽象,并且几乎总是可以做我想要的。理论上箭头更强大,但我没有发现自己在实践中使用它们。

关于haskell - 箭头完全等同于应用仿函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24668313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com