为什么相互让步使 ArrowApply 和 Monads 等效,而不像 Arrow 和 Applicative?

2024-01-01

这是我要参考的SO帖子 https://stackoverflow.com/a/24668518/11143763. 另外,我将使用与该问题中的OP相同的片段,以免分离材料 https://stackoverflow.com/q/24668313/11143763.

It is 众所周知 https://hackage.haskell.org/package/base-4.12.0.0/docs/src/Control.Arrow.html#ArrowApply那一个ArrowApply实例产生一个 Monad,反之亦然:

newtype ArrowMonad a b = ArrowMonad (a () b)

instance Arrow a => Functor (ArrowMonad a) where
    fmap f (ArrowMonad m) = ArrowMonad $ m >>> arr f

instance Arrow a => Applicative (ArrowMonad a) where
   pure x = ArrowMonad (arr (const x))
   ArrowMonad f <*> ArrowMonad x = ArrowMonad (f &&& x >>> arr (uncurry id))

instance ArrowApply a => Monad (ArrowMonad a) where
    ArrowMonad m >>= f = ArrowMonad $
        m >>> arr (\x -> let ArrowMonad h = f x in (h, ())) >>> app

newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }

instance Monad m => Category (Kleisli m) where
    id = Kleisli return
    (Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)

instance Monad m => Arrow (Kleisli m) where
    arr f = Kleisli (return . f)
    first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
    second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))

直到我偶然发现post https://stackoverflow.com/a/24668518/11143763上面提到,我觉得这个片段是等价的合理证明ArrowApply and Monad类。然而,拥有这样的知识事实上,箭头和应用并不等同 https://stackoverflow.com/a/24668518/11143763下面的代码片段让我对等价性的完整证明感到好奇Monad and ArrowApply:

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)

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

因此,如果您往返应用程序,您会失去一些功能。 https://stackoverflow.com/q/24668313/11143763

写下的示例很明显,但我无法理解通过 Monad 的“往返”如何保留所有 ArrowApply 功能,因为最初我们有一个取决于某些输入的箭头(a b c)但最终,我们最终得到了一个强制进入包装器的箭头,该包装器以单位类型作为其输入类型(ArrowMonad (a () b)).

很明显,我在这里做了一些非常错误的事情,但我无法理解到底是什么。

充分的证明是什么ArrowApply and Monad是等价的?

不等价的例子有哪些Arrow and Applicative占?一个人是否概括了另一个人?

箭头微积分和范畴论对整个情况的解释是什么?

我希望得到完整的解释和提示,它们可以帮助人们自己起草一份看似合理的证据。


因为最初我们有一个箭头,它取决于一些输入(a b c)但最终,我们最终得到了一个强制进入包装器的箭头,该包装器以单位类型作为其输入类型(ArrowMonad (a () b))

我想这就是令人困惑的中心点,而且确实令人困惑。我喜欢将箭头视为笛卡尔幺半群范畴中的态射,你不会明白这一点,但已经Arrow类实际上比这更受限制,这要归功于arr– 这给你一个函子Hask进入类别。但是,有点令人惊讶的是,这还需要您在other方向:任何箭头都可以替换为function这仅产生一个平凡域的箭头。具体来说,

arrAsFunction :: Arrow k => k x y -> (x -> k () y)
arrAsFunction φ x = φ <<< arr (const x)

好吧,仅此一点并不算太具有开创性——也许我们只是在这里丢弃了一些信息? – 但与ArrowApply这实际上是一个同构:您可以通过以下方式取回原始箭头

retrieveArrowFromFunction :: ∀ k x y .
          ArrowApply k => (x -> k () y) -> k x y
retrieveArrowFromFunction f = arr f' >>> app
 where f' :: x -> (k () y, ())
       f' x = (f x, ())

...这正是在中使用的Monad (ArrowMonad a)实例。

所以结果是:arr,通过要求您可以在类别中嵌入任何 Haskell 函数,强制类别基本上归结为对结果进行一些包装的函数,IOW 类似 Kleisli 箭头的东西。

查看其他一些范畴论层次结构,看看这是not笛卡尔幺半群范畴的基本特征,但实际上是Haskk函子。例如。在受限类别中 http://hackage.haskell.org/package/constrained-categories-0.4.0.0/docs/Control-Arrow-Constrained.html#t:PreArrow我已经密切反映了标准课程,PreArrow作为笛卡尔幺半群类别的类,但故意保留arr并没有具体说明Hask,因为这大大降低了该类别的功能,并导致它几乎等同于Hask-克莱斯利。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么相互让步使 ArrowApply 和 Monads 等效,而不像 Arrow 和 Applicative? 的相关文章

  • 使用默认值压缩而不是删除值?

    我正在 haskell 中寻找一个函数来压缩两个长度可能不同的列表 我能找到的所有 zip 函数都只是删除列表中比其他列表长的所有值 例如 在我的练习中 我有两个示例列表 如果第一个比第二个短 我必须用 0 填充 否则我必须使用 1 我不允
  • 在 Archlinux 上使用 Vim 作为 Haskell 的 IDE 目前情况如何?

    如果可行的话 我的目标是通过 YouCompleteMe 在 Vim 中完成 Haskell 的命令 在这方面 正如您在下面看到的 我还没有找到关于如何让它发挥作用的共识 相关评论的最新评论YouCompleteMe 上的问题 https
  • Haskell Cabal:“包间接依赖于同一包的多个版本”

    清除我的所有后cabal installed 包 我运行了以下会话 cabal update Downloading the latest package list from hackage haskell org james bast c
  • Cabal:使用源代码构建目录

    我有一个src目录 在这个目录中我有Main hs文件和Test目录 在里面Test我有的目录Test hs模块 我需要用 cabal 来编译它 在我的阴谋集团文件中 我有 Executable main hs or lhs file co
  • 承诺的反面是什么?

    承诺代表将来可能可用 或无法实现 的值 我正在寻找的是一种数据类型 它表示将来可能变得不可用的可用值 可能是由于错误 Promise a b TransitionFromTo
  • HASKELL:解决河内塔

    下面的代码解决了 hanoi 使用预定义函数 moveLOD swapLOI 和 swapLID 返回移动列表的问题 MoveLOD 将 1 个圆盘从第一个位置移动到三元组第三个位置中的第三个销钉 此外 包含有关运动信息的字符串会堆积在字符
  • 为什么对本地列表求和比用“GHC -O2”对教会编码列表求和慢?

    为了测试教会编码的列表如何针对用户定义的列表和本机列表执行 我准备了 3 个基准测试 用户定义的列表 data List a Cons a List a Nil deriving Show lenumTil n go n Nil where
  • 过滤路径列表以仅包含文件

    如果我有一个清单FilePaths 如何过滤它们以仅返回常规文件 即不是符号链接或目录 例如 使用getDirectoryContents main do contents lt getDirectoryContents foo bar l
  • monadicIO 的工作原理

    我有以下代码 fastShuffle a gt IO a fastShuffle a
  • Haskell 有 takeUntil 函数吗?

    目前我正在使用 takeWhile x gt x 1 x 89 l 从列表中获取最多为 1 或 89 的元素 但是 结果不包括这些标记值 Haskell 是否有一个标准函数可以提供这种变化takeWhile结果中包含哨兵 到目前为止 我对胡
  • 如何在Haskell中定义一个允许统一访问不同记录的类?

    我有两条记录 它们都有一个我想要提取以显示的字段 我如何安排事物以便可以使用相同的功能来操纵它们 由于它们有不同的字段 在本例中firstName and buildingName 这是它们的名称字段 它们每个都需要一些 适配器 代码来映射
  • Pandoc“无法找到已安装模块的模块...”

    我目前正在尝试使用 pandoc 作为 Haskell 模块 而不是程序 将 MediaWiki 文本转换为其他格式 我们假设这个程序 import Text Pandoc Readers MediaWiki main do print f
  • 具有运行时错误的 Foldl 实现

    向你学习 Haskell http learnyouahaskell com higher order functions folds解释foldl1 Foldl1 和 Foldr1 函数的工作方式与 Foldl 和 Foldr 非常相似
  • 运行程序的最佳 Haskell 库是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 如果我要将一个程序投入生产 我需要该程序做几件事才能将其视为 可操作 也就是说 工程师和操作人员以可测量
  • 为自定义镜头编写类别实例

    我一直在读这个article http www haskellforall com 2012 01 haskell for mainstream programmers 28 html用于理解镜头 我知道这不同于 爱德华 克内特 Edwar
  • 如何使用 alex/haskell 执行 python 风格的缩进/缩进标记?

    我正在用 Haskell 为 Alex 中的一种小语言编写一个词法分析器 该语言被指定为具有 python 式的显着缩进 只要缩进级别发生变化 就会发出 INDENT 标记或 DEDENT 标记 在像 C 这样的传统命令式语言中 您将在词法
  • 测试列表是否已排序

    在 haskell 中找到最小列表确实很容易 foldl1 min 9 5 7 3 7 4 6 10 给我3 我更换了min with lt 测试列表是否已排序 foldl1 lt 9 5 7 3 7 4 6 10 我收到此错误消息 No
  • 在 win32/cygwin 上编译 haskell 模块网络

    我正在尝试编译 Network HTTP http hackage haskell org package network http hackage haskell org package network 在 win32 cygwin 上
  • 哈斯克尔状态单子

    是否putState Monad 的函数会更新实际状态还是仅返回具有新值的新状态 我的问题是 State Monad 可以在命令式设置中像 全局变量 一样使用吗 并且确实put修改 全局变量 我的理解是 不 它不会修改初始状态 但是使用单子
  • 当单态限制打开*时,如何解决歧义问题?

    因此 在学习 Haskell 时 我很快就遇到了可怕的单态限制 在 ghci 中 Prelude gt let f print show Prelude gt f 5

随机推荐