parameter to anonymous function
How do you send a parameter to an anonymous funct开发者_如何学Pythonion in scala, i'm trying to translate this from scheme
(cdr (map (lambda (x) (* x x)) somelist )
i know cdr is just .tail
and that an anonymous function is like (x: Int) => x * 2, 9
any help appreciated.
You have to make two kinds of translation here:
From prefix notation (function precedes arguments) to infix/postfix notation (method between object and parameters).
From functional (function and data are not tightly bound) to object oriented (methods are bound to objects).
I'll use the dot notation in Scala, to make things more clear.
So, in Lisp you have (function arguments)
, so it is pretty easy to identify what are the arguments to each function. In Scala you have object.method(parameters)
, so let's go through each Lisp function to identify what are the arguments and what is the object.
On the other hand, some Lisp functions will do some operation to every argument it receives, which doesn't translate to how Scala methods work. In these cases, one would need to introduce additional methods to translate, most often a sequence's map
.
CDR
As you mentioned, this is Scala's tail
. Alas, tail
is a parameterless method, and cdr
only receives a single parameter as well, so there's no need to further translation. Therefore,
(cdr (map (lambda (x) (* x x)) somelist))
becomes a partially translated
(map (lambda (x) (* x x)) somelist ).tail
MAP
There's a missing argument in the example given, which is the result type. So let's assume there was a 'list
there. The translation here is more tricky, because map
, in Scala, is a method on a collection, not on a function. So it is somelist
which is the object, and (lambda (x) (* x x))
the method's parameter.
The translation, then, is from the partially translated
(map (lambda (x) (* x x)) somelist).tail
to the still partially translated
somelist.map(lambda (x) (* x x)).tail
LAMBDA
This one is more tricky, as there is no method in Scala that is its equivalent, and there couldn't be, as no method would be able to bind variables. However, lambda
is intrinsic to the language, with the following syntax:
(argument list) => expression
Therefore,
(lambda (x) (* x x))
translates (partially) into
((x) => (* x x))
Back to the example, we have
somelist.map(lambda (x) (* x x)).tail
becoming
somelist.map((x) => (* x x)).tail
There are two important points to make here, though. First, Lisp is dynamically typed, so there is no need to declare what is the type of x
. That is not the case for Scala, which can make things difficult, as there is no common type for all numbers.
The second point, though, is that Scala has type inference, so it can infer the type of x
from the type of somelist
, which renders the above point moot in this particular case.
Finally,
*
Which can be often more tricky, because it does apply to however many arguments you have. The usual translation of
(* arguments)
is
collection.reduceLeft((x, y) => x * y)
Where collection
is some sort of collection containing all of the arguments
.
In this case, however, there are exactly two arguments, so it can be translated to Scala's own *
. So, for the final part of the translation, we take
somelist.map((x) => (* x x)).tail
and turn it into
somelist.map((x) => x * x).tail
I hope somewhere along the way there was the answer to your doubts.
I'm not quite sure what the question is, so this is to spark some more information (or other answers) than anything else:
List(1,2,3) map (x => x * x) tail // => List(4,9)
This is the same as:
//blasted Scala still gets me -- List(1,2,3).map(x => x * x).tail()
List(1,2,3).map(x => x * x).tail
Where x => x * x
is the 'lambda' in both cases.
Above the type can be omitted because it can be inferred. However,
// need the type here because it can't be inferred from context
val square = (x: Int) => x * x
I am not sure what you want, I don't know scheme, maybe this one:
val a = (x:Int) => x * 2
List(1,2,3).map(a)
List(1,2,3).map(_ * 2)
精彩评论