Scala语法帮助咖喱 [英] Scala Syntax Help Currying

查看:100
本文介绍了Scala语法帮助咖喱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在scala中以类似的形式遇到了一些代码:

I came across some code in scala in a similar form like this:

  def test1(f : Int => Int)(x : Int) = x + f(x)

  def test2(f : Int => Int)(x : Int) = f(x)

  test2(test1(x => 2*x))(2)

我很困惑,所以函数test1将一个函数和一个Int作为参数,然后返回一个函数,对吗?那么test1(x => 2*x)如何有效并将函数返回给test2?显然,它需要2作为整数参数,但是为什么呢?语句test2(test1(x => 2*x))(2)如何扩展?

I'm confused, so function test1 takes a function and a Int as parameters, and returns a function, right? Then how can test1(x => 2*x) be valid and returns a function to test2? Apparently it takes 2 asthe integer parameter, but why? How does the statement test2(test1(x => 2*x))(2) expand?

先谢谢了.

推荐答案

此:

test2(test1(x => 2*x))(2)

扩展为:

test2(y => test1(x => 2*x)(y))(2)

Scala具有多个参数列表的方法可以像其他语言中的咖喱函数一样工作,但实际上是作为需要其所有参数的方法实现的,这确实在语法中得以体现.例如,如果您将其放入REPL中:

Scala's methods with multiple argument lists can act a lot like curried functions in other languages, but in fact are implemented as methods that requires all of their parameters, and this does show through in the syntax. For example if you put this into the REPL:

test1(x => 2*x)

它将抱怨缺少参数.此语法允许的是"eta扩展",其中方法被转换为函数.如果您写:

It will complain about missing arguments. What this syntax does allow is "eta-expansion", where a method is converted into a function. If you write:

val func: Int => Int = test1(x => 2*x) _

您可以获得代表部分应用的test1的函数.如果上下文需要,Scala将自动执行eta扩展,这是test2(test1(x => 2*x))(2)会发生的情况.请注意,test1本身从不返回函数,但是编译器将在需要时基于该函数构建函数.

You can get a function that represents test1 partially applied. Scala will do eta-expansion automatically if the context requires it, which is what happens with test2(test1(x => 2*x))(2). Note that test1 itself never returns a function, but the compiler will build a function based on it when required.

但是,如果您将test1定义为:

However, if you define test1 like:

def test1(f : Int => Int) = (x : Int) => x + f(x)

然后,编译器将接受不带_test1(x => 2*x).同样,在基础实现中,只有一个类实现由test1表示的闭包,而对于原始定义,test1的每个部分应用都会为其创建一个新类.另一方面,给定两个参数时效率较低,因为总是创建闭包.

Then the compiler will accept test1(x => 2*x) without the _. Also, in the underlying implementation there will be only one class implementing the closure retured by test1, whereas with the original definition every partial application of test1 causes a new class to be created for it. On the other hand, it is less efficient when given both parameters, because the closure is always created.

这篇关于Scala语法帮助咖喱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆