当前位置: 首页 > 知识库问答 >
问题:

用函数组合理解映射函数

闽经纬
2023-03-14

我有以下Haskell表达式:

let increment x = 1 + x
in \xs -> map chr (map increment (map ord xs))

而我也有下面的表达:

map chr . map (1+) . map ord

我正试图弄清楚上面是否等同于第一个表达式。然而,当我在GHCI中尝试上面的表达式时,我得到了一个错误:

map chr . map (1+) . map ord ['a', 'b', 'c', 'd', 'e']

我不知道为什么这个表达不起作用。既然使用了函数组合,那么表达式的计算值不应该是:

(map chr (map (1+) (map ord ['a', 'b', 'c', 'd', 'e'])))

共有1个答案

奚英朗
2023-03-14

运算符(定义为名称中没有字母数字字符的函数,以中缀样式使用)的优先级低于Haskell中的其他函数。因此你的表达:

map chr . map (1+) . map ord ['a', 'b', 'c', 'd', 'e']

解析为:

(map chr) . (map (1+)) . (map ord ['a', 'b', 'c', 'd', 'e'])

这没有任何意义-.运算符组合了2个函数,映射ord['a'、'b'、'c'、'd'、'e']不是一个函数,而是一个数字列表。

但是对于所有嵌套括号的正确版本,仍然有更好的替代方案。您要做的是从字符列表开始,然后在其上依次映射3个函数。根据函数组合的定义,这与将3映射的组合应用于函数组合是相同的,即:

(map chr . map (1+) . map ord) ['a', 'b', 'c', 'd', 'e']

正如@chi在下面指出的那样,它通常是这样编写的,使用函数应用程序操作符$(它的优先级比任何其他操作符都低)来避免任何圆括号:

map chr . map (1+) . map ord $ ['a', 'b', 'c', 'd', 'e']

而且,因为映射f。map g总是与map(f.g)相同(当您停下来思考这些表达式的含义时,这一点应该很明显--这也是map操作必须满足的基本定律,以便将列表类型变成函式),这可以被写成:

map (chr . (1+) . ord) ['a', 'b', 'c', 'd', 'e']

在我看来,这是最好的,可读性最强的版本。

尽管正如@chi再次指出的那样,使用chr更好。(1+)。ord等效于succ,后者是用于获取可枚举类型的“Next”值的内置函数。所以您只需编写映射succ['a','b','c','d','e']

 类似资料:
  • 我对流图法有点困惑。有一些简单的源代码可以运行: map()签名:Stream map(函数 在我的选择中,我认为赋予文字的功能。stream()。map应该有1个参数,但是string::length没有任何输入参数,只返回int。 它看起来像word流调用字符串中的每个元素“word”。长度(),但我不知道该怎么做?为什么string::length签名不需要与函数签名(R apply(T))

  • 映射函数是一组可以连续应用于一个或多个元素列表的函数。 将这些函数应用于列表的结果将放在新列表中,并返回新列表。 例如, mapcar函数处理一个或多个列表的连续元素。 mapcar函数的第一个参数应该是一个函数,其余参数是应用函数的列表。 参数函数应用于导致新构造的列表的连续元素。 如果参数列表的长度不相等,则映射过程在到达最短列表的末尾时停止。 结果列表将具有与最短输入列表相同数量的元素。 例

  • 我遇到过一些不同寻常且有趣的技术,以及使用Spring云函数拆分业务和技术实现的方法,该函数支持java的实现。util。函数类充当endpoint 简而言之,有一个简单的静态列表 下面的Bean根据方法名称及其返回类型启用指定的endpoint: 问题: > 可以使用java中的一个或多个类来实现完全兼容REST的解决方案。util。功能组合?我只能写上面的那些。我对以下模式特别感兴趣: 如何避

  • 我有一小段代码,用于计算给定数组中的正值、负值和零值的数量。使用Java 7,通过迭代数组并计算正值、负值和零值的数量,我可以轻松地做到这一点。但对于Java 8流,在map函数中写入条件是否正确?目前,此代码只迭代一次,并跳过数组的其余值。

  • 我试图收集一个列表的结果,并将它们组织成一个地图,其中的值是一个地图: 我得到错误,因为对于列表中的不同值是相同的。 映射中包含的值应为: 当我尝试会删除其中一个条目

  • 我目前正在阅读一本Java8Lambdas的书(相当受欢迎),我对其中一个高级问题的答案中的一些语法感到困惑。 问题提出如下问题: 只使用reduce和lambda表达式编写函数'map'的实现。您可以返回而不是。 到目前为止,Java8 lambdas已经非常简单了,我觉得我似乎理解了书中的所有理论,但也许我误解了什么?我想知道我在这里错过了什么?