我正在尝试学习SML,我的一些教授笔记谈论了map
函数,它有类型('a - >'b) - >('a list - >'b列表)。”他继续解释说这意味着“你给我一个功能,将's变成'b'......”。
但是,他的实现看起来像:
fun map f [] = []
| map f (a::l) = (f a)::(map f l)
在我看来,它占用了相当于2个参数(我知道sml中的所有内容在技术上只接受一个参数,但使用元组或currying它看起来像2)。看起来它正在采用功能和列表。但是,上面的解释使它听起来只是一个功能。我错过了什么?
答案 0 :(得分:4)
正如你自己说的,SML并不具有多元函数,它只模拟使用元组或currying。在这种情况下,map
是一个curried函数。你的教授陈述有道理的原因是,一个curried函数只是一个函数,它接受一个参数并返回一个接受下一个参数的函数。
查看此内容的一种方法是根据fun
重写val
。一般来说,fun f x y = bla
相当于val rec f = fn x => fn y => bla
。所以map
的定义可以等效地写成:
val rec map = fn f => fn as => case as of
[] => []
| (a::l) => (f a)::(map f l)
查看该定义很明显,第一个fn
创建了一个返回另一个函数的函数(第二个fn
)。
通过观察只用一个参数调用map
并且结果是函数是合法的,我们也可以看到这种情况:
val my_map = map my_function
val mapped_list = my_map my_list
上述my_map my_list
相当于map my_function my_list
。这告诉我们,由于函数应用程序是左关联的,调用map my_function my_list
(相当于(map my_function) my_list
)只需使用参数map
调用my_function
,然后调用函数重新调用以map
为my_list
作为参数。
这就是currying的全部内容。