函数 monad 真的能提供比函数应用函子更多的东西吗?如果是这样,什么?

如何解决函数 monad 真的能提供比函数应用函子更多的东西吗?如果是这样,什么?

对于函数 monad,我发现 (<*>)(>>=)/(=<<) 有两种非常相似的类型。特别是,(=<<) 使相似性更加明显:

(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
(=<<) :: (a -> r -> b) -> (r -> a) -> (r -> b)

所以它就像 (<*>)(>>=)/(=<<) 都取一个二元函数和一个一元函数,并且 constrain 前者的两个参数之一被确定从另一个,通过后者。毕竟,我们知道对于函数 applicative/monad,

f <*> g = \x -> f x (g x)
f =<< g = \x -> f (g x) x 

而且它们看起来非常相似(或者对称,如果你愿意的话),我不禁想起标题中的问题。

关于 monad 比应用函子“更强大”,在 LYAH's For a Few Monads More chapter 的硬拷贝中,声明如下:

[…] join 不能仅使用函子和应用程序提供的函数来实现。

join 不能在 (<*>)purefmap 方面实现。

但是我上面提到的 function applicative/mondad 呢?

我知道 join === (>>= id) 以及归结为 \f x -> f x x 的函数 monad,即通过将后者的一个参数作为前者的两个参数提供给二元函数使二元函数成为一元函数。

我可以用(<*>)来表达吗?好吧,实际上我认为我可以:flip ($) <*> f === join f 是不是正确的? flip ($) <*> f 不是没有 join/(>>=)(=<<)return 的实现吗?

然而,考虑到列表 applicative/monad,我可以在不显式使用 join/(=<<)(>>=)(甚至不使用 return,fwiw): (<*>);因此,实现 join = concat 也可能是一种技巧,并没有真正显示出我是仅依赖于 join f = flip ($) <*> f 还是还依赖于 Applicative

解决方法

当您像这样实现 join 时,您使用的函数类型知识超出了 Applicative 所提供的知识。这些知识在 ($) 的使用中被编码。那就是“应用程序”运算符,它甚至是函数的核心。您的列表示例也会发生同样的情况:您使用的是 concat,它基于对列表性质的了解。

通常,如果您可以使用特定 monad 的知识,则可以表达任何幂的计算。例如,使用 Maybe,您可以匹配其构造函数并以这种方式表达任何内容。当 LYAH 说 monad 比 applicative 更强大时,它的意思是“作为抽象”,不适用于任何特定的 monad。

,

edit2: 这个问题的问题在于它含糊不清。它使用了一个根本没有定义的概念(“更强大”),让读者猜测其含义。因此我们只能得到毫无意义的答案。当然,在使用我们可以使用的所有 Haskell 库时,任何东西都可以编码。这是一个空洞的说法。这不是问题。

就我所见,澄清的问题是:分别使用 Monad / Applicative / Functor 中的方法作为 primitives,根本不使用显式模式匹配,是因此,对于使用中的一组或另一组原语,可以严格表达为更大的计算。现在这个可以得到有意义的回答。

虽然函数是不透明的。无论如何都不存在模式匹配。在不限制我们可以使用的情况下,这个问题同样没有意义。然后限制就变成了显式使用命名参数、有针对性的编程风格,因此我们只允许自己以组合风格进行编码。

那么,对于列表,仅使用 fmapapp (<*>),我们可以表达如此多的计算,并且将 join 添加到我们的武器库确实可以那个更大。函数不是这样。 join = W = CSI = flip app id。结束。

实现了app f g x = (f x) (g x) = id (f x) (g x) :: (->) r (a->b) -> (->) r a -> (->) r b,我已经有了flip app id :: (->) r (r->b) -> (->) r b,我不妨称它为join,因为类型合适。无论我写与否,它都已经存在。另一方面,从 app fs xs :: [] (a->b) -> [] a -> [] b,我似乎无法得到 [] ([] b) -> [] b-> 中的两个 (->) r (a->b) 都是相同;函数 special

(顺便说一句,我目前不知道如何在不实际将 app 编码为嗯。使用列表推导式等同于使用 join;而 concat 不是 concat 的实现,它 {{1 }}).


join

很简单,所以毫无疑问。


编辑:好吧,显然还有疑问)。

join 用于函数。而已。这就是函数 Monad 和 Applicative Functor 是相同的意思。 join f = f <*> id 是一个普遍适用的组合子。 (=<<) = (<*>) . flip 不是。那里有一定的混淆,当然,功能。但是那里或任何地方都没有特定的函数操作函数(例如 flip 是一个特定的列表操作函数),因为函数是不透明的。

作为一种特定的数据类型,它可以进行模式匹配。作为一个 Monad,虽然它只知道 concatconcat>>= 确实使用模式匹配来完成其工作。 return 没有。

concat 在这里类似于列表的 id,而不是 id。它的工作原理正是这意味着被视为 Applicative Functor 或 Monad 的函数是相同的。当然,总的来说 Monad 比 Applicative 更强大,但这不是问题。如果您可以用 []concat 表示列表的 join,我会说这意味着它们对列表也具有相同的功能。

<*> 中,[](=<<) = (<*>) . flip 对它们应用的函数没有任何作用。所以他们不知道这些函数的内部结构。就像,flip 将碰巧正确计算参数列表的长度,如果该列表是例如(.)。说this,建立在this之上,使用函数foo = foldr (\x acc -> x+1) 0的一些内部知识(与[1,2]相同,使用通过模式匹配了解其参数列表的内部知识)。但仅使用 fooconcat 等基本组合符不是。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res