我无法理解Rosetta Code中的这个矩阵乘法示例:
(define multiplyMatrices
(lambda (matrix1 matrix2)
(map (lambda (row)
(apply map (lambda column
(apply + (map * row column)))
matrix2))
matrix1)))
其中matrix1
和matrix2
都是列表。我的问题是:为什么第四行的column
没有用括号括起来?
据我了解,lambda
表达式的格式为(lambda (<id1 id2 ...>) <exp>)
。从测试代码我知道它的工作原理,我知道在括号中包装column
确实会破坏程序,但我不明白该行是如何语法的,以及我找到的lambda
表达式的每个解释在线总是像我上面那样描述它们。
答案 0 :(得分:3)
其他答案是正确的,但我想指出这不是一种特殊的语法,而是涉及 rest参数的更一般语法的特定情况。
考虑以下功能:
(lambda () ...)
(lambda (first) ...)
(lambda (first second) ...)
(lambda (first second third) ...)
这些函数分别采用0,1,2和3个参数。
现在考虑以下这些功能:
(lambda rest ...)
(lambda (first . rest) ...)
(lambda (first second . rest) ...)
(lambda (first second third . rest) ...)
这些函数分别使用至少 0,1,2和3个参数。在这些情况下,任何进一步的参数都会被收集到列表中并绑定到rest
。
第一组函数使用正确列表作为lambda列表。第二组函数使用不正确列表作为其lambda列表。那两者之间的区别是什么? 正确的列表只是一个列表,其中()
作为最终的cdr,不正确的列表是一个列表,其他东西作为其最终的cdr。就是这么简单。
为了在两组函数之间提供更大的视觉对称性,可以用这种方式编写第一组函数:
(lambda () ...)
(lambda (first . ()) ...)
(lambda (first second . ()) ...)
(lambda (first second third . ()) ...)
列表(first second third)
与<{1}}完全相同。读入这些表达式后,无法区分这两个表达式。
答案 1 :(得分:1)
此语法将所有参数放入列表中:
(define test (lambda x x))
(test 1)
=> '(1)
(test 1 2 3)
=> '(1 2 3)
(test '(1 2 3))
=> '((1 2 3))
另请参阅here:“如果形式是单个变量(不在列表中),例如z,则它绑定到实际参数列表。”
答案 2 :(得分:0)
注意以下两个函数之间的区别:
> (define f1 (lambda (x) x))
> (f1 "HELLO")
"HELLO"
和
> (define f2 (lambda y y))
> (f2 "HELLO")
'("HELLO")
在scheme中调用函数时,参数绑定到函数的参数列表。由于f1
的参数列表是(x)
(括号括起来),列表是 destructured ,因此x
指的是列表中的一个参数被传递给了它。
f2
在其参数列表y
周围不包括括号,因此发送给它的参数列表不会被解构,因此返回列表。