“双右箭头类型"是什么意思在函数参数中没有 LHS 均值 [英] What does "double right-arrow Type" with no LHS mean in function argument
问题描述
我无法解释指定为没有 LHS(左侧)的函数参数的双右箭头类型",例如<代码>() =>Int 是从 ()
到 Int
但是只有 =>int
是什么意思?例如看下面foo
方法的第一个参数,f
的类型是什么?是 (Int, () => Int) =>整数
?
I am having trouble interpreting "double-rightarrow Type" specified as a function argument without a LHS (left hand side) e.g. () => Int
is from ()
to Int
but what does just => Int
mean?
e.g. see the first argument of foo
method below, what is the type of f
? Is it (Int, () => Int) => Int
?
对于 bar
的定义,其中 y 是按名称传递的,我将它解释为一个没有参数的函数,它将产生一个 Int,它看起来等同于 baz 的定义代码>.
For the definition of bar
, where y is passed by name, I've interpreted it as a function with no argument that will produce an Int, which looks equivalent to definition of baz
.
我可以推断 foo
中的 f
将第二个参数作为按名称调用,而不是来自 () =>Int
但这与 javap 中 bar
和 baz
定义相同的事实相矛盾.我错过了什么?
I could try to reason that f
in foo
takes the second argument as call by name, and is not from () => Int
but that is contradicting that fact that bar
and baz
definitions are identical in javap. What am I missing?
object ParamTest {
def foo(f: (Int, => Int) => Int, x: Int) : Int = 10
def bar(x: Int, y: => Int) : Int = 20
def baz(x: Int, f: () => Int) : Int = 30
def qux(f: (Int, () => Int) => Int, x: Int) : Int = 40
}
为了测试,我用 scalac ParamTest.scala
javap ParamTest
给我:
public final class ParamTest {
public static int qux(scala.Function2<java.lang.Object, scala.Function0<java.lang.Object>, java.lang.Object>, int);
public static int baz(int, scala.Function0<java.lang.Object>);
public static int bar(int, scala.Function0<java.lang.Object>);
public static int foo(scala.Function2<java.lang.Object, scala.Function0<java.lang.Object>, java.lang.Object>, int);
}
这似乎表明 foo 和 qux 具有相同的方法签名.换句话说,我可以解释 =>Int
as () =>Int
,但是foo(baz,100)
给我一个类型不匹配错误
That seems to indicate that foo and qux have the same method signature. In other words, I could interpret => Int
as () => Int
, but
foo(baz,100)
gives me a type mismatch error
scala> import ParamTest._
import ParamTest._
scala> foo(bar,100)
res0: Int = 10
scala> foo(baz,100)
<console>:11: error: type mismatch;
found : (Int, () => Int) => Int
required: (Int, => Int) => Int
foo(baz,100)
^
编辑:这与这个问题不同.我不是在问 call-by-name: =>;输入
和() =>输入
.我更感兴趣的是内部结构.当 javap 或 cfr 反编译 给我相同的定义时,Scala 如何区分这两者code>foo 和 qux
;以及 bar
和 baz
.
EDIT: This is not the same as this question. I'm not asking the practical difference between call-by-name: => Type
and () => Type
. What I'm more interesting in knowing is the internals. How does scala differentiate between the two, when javap or cfr decompilation gives me identical definitions for foo
and qux
; and for bar
and baz
.
推荐答案
正如你所发现的,() =>A
和 =>A
不是一回事.
As you've discovered, () => A
and => A
are not the same thing.
按名称调用(即 => A
)仅表示:延迟对该方法参数的评估."换句话说,惰性求值.
Call by name (i.e. => A
) simply means: "delay the evaluation of this method argument." In other words, lazy evaluation.
def f(x: Int, y: => Int) = ???
f(3+5, 2+4)
在这个例子中,3+5 的加法是在调用点完成的,x
值为 8.另一方面,2+4 的加法直到 y
在方法 f()
的主体内被引用.如果该引用位于未执行的 if...else...
分支中,则永远不会完成添加.
In this example the addition of 3+5 is done at the call site and the x
value is 8. The addition of 2+4, on the other hand, isn't done until y
is referenced inside the body of the method f()
. If that reference is in an if...else...
branch that doesn't get executed then the addition is never done.
这对于像 Int
加法这样的简单计算来说毫无意义,但是如果参数是一个昂贵的计算,或者它是一个有副作用的代码块,它就会变得更有意义.
This is pretty pointless for simple evaluations like Int
addition, but it becomes more meaningful if the argument is an expensive evaluation, of if it's a block of code with side effects.
所以,在回答你的问题时,f 的含义是:(Int, => Int) =>Int
是: "f
接受两个参数并产生一个 Int
,参数是 2 个 Int
,其中的第二个是懒惰地评估."
So, in answer to your question, the meaning of f: (Int, => Int) => Int
is: "f
takes two arguments and produces an Int
, the arguments are 2 Int
s, the 2nd of which is evaluated lazily."
这篇关于“双右箭头类型"是什么意思在函数参数中没有 LHS 均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!