在Scala中使用无点样式的理由

25

对于函数式编程专家来说,这可能看起来非常明显,但是点无风格在Scala中有什么好处呢?一个能够真正让我相信的例子是,展示如何使用点无风格比非点无风格解决同一问题的代码在某些方面(例如性能、优雅性、可扩展性、可维护性)显着更好。


4
对于非平凡的例子来说,Scala 并不是最适合用于无参编程的语言。在某些情况下,类型推断器会要求你提供类型相关的确切信息,或者需要使用 _ 将方法转换为函数进行隐式评估,这让人怀疑结果是否真正符合“无参”的定义。 - Debilski
4个回答

25

简单来说,这是关于能够避免在不需要的情况下指定名称的能力,考虑一个微不足道的例子:

List("a","b","c") foreach println
在这种情况下,foreach 希望接受 String => Unit,一个接受一个字符串并返回 Unit 的函数(基本上它没有可用的返回值,而是通过副作用来工作)。
这里不需要为传递给 println 的每个字符串实例绑定名称。可以说,这只会使代码变得更加冗长:
List("a","b","c") foreach {println(_)}

甚至更多

List("a","b","c") foreach {s => println(s)}

个人而言,当我看到没有采用点分风格的代码时,我认为这表明绑定名称可能会被使用两次,或者在记录代码方面有一定的重要性。同样地,我认为点分风格是我可以更简单地推理代码的标志。


甚至可以使用 List("a","b","c") foreach println - aeracode
在Scala中,点无风格最有益的地方是函数定义+函数组合,我认为。它允许您完全省略命名参数,并完全集中于函数的组合。如果您有3个接受Seq并返回Seq的函数,则do123:Seq [A] => Seq [A] = f1 andThen f2 andThen f3更简单且更具表现力。但是,这仅适用于函数的组合,而不适用于方法。一旦混合了方法,它就变得更加丑陋。 - itsbruce
2
点无编程不是将函数绑定到对象上,而是通过组合函数来编写程序:val squareList = map square这可能是一种表示方法,Scala 是否支持这种表示方法?《学习 Haskell》中的一个示例如下:listFn = map (negate . sum . tail) - vamsiampolu
1
这里提供了一份关于pointfree风格的解释:http://www.scala-lang.org/old/node/9371.html - vamsiampolu
1
@vamsiampolu 我来这里也是为了弄清楚这个问题,看起来你可以定义自己的函数,但似乎Scala社区还没有使用这种方式: def always[A, B]: A => B => A = x => y => x val dingoMap = map(always("dingo")) dingoMap(List(1, 2, 3)) // -> List("dingo", "dingo", "dingo") - AndrogenAgonist
显示剩余2条评论

5

点无风格(point-free style)的一个吸引力在于,没有一堆“点”(值而不是函数)漂浮在周围,必须在多个地方重复它们以将它们穿过计算,这样就减少了出错的机会,例如输入变量名称时。

然而,在Scala中,点无风格的优势很快被其贫瘠的类型推断能力所抵消,这一事实由于“点”作为类型推断器的线索而加剧。在Haskell中,由于其几乎完整的类型推断,这通常不是问题。


是的,点无风格编程风格可以帮助您避免编码错误,例如使用错误的循环变量。另一方面,这种错误通常并不难发现。 - enhanced_null

1

我认为使用这种方式的优点只有“优雅”:它会稍微缩短代码,可能更易读。它允许将函数视为实体进行推理,而无需在脑海中深入一层进行函数应用,但当然您需要先适应它。

我不知道任何可以通过使用它来提高性能的例子(也许在您最终需要一个方法而得到一个函数时,情况会变得更糟)。


-5

Scala的无参语法是Scala运算符的一部分,这些运算符实际上是函数。即使是最基本的运算符也是函数:

例如:

val x = 1
val y = x + 1

...与...相同。

val x = 1
val y = x.+(1)

...但是当然,点无风格的写法更自然(加号看起来像一个运算符)。


3
抱歉,我没有意识到“point-free”还有一个不太明显的含义。也许您可以解释一下“point-free”的意思,以避免以后的混淆? - Jim Hurne
5
简而言之,这意味着省略函数参数的明确引用,或者仅使用函数定义函数。在评论中有点难以解释。 - Debilski
4
感谢你的误解,因为这也是我的误解,并且坚持进行有益的对话以获取一些有用的链接。 :-) - Lutz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接