Nos*_*tap 2 function sml smlnj
我正在查看我的教授给出的关于语言SML的一些注释,其中一个函数如下所示:
fun max gt =
let fun lp curr [] = curr
| lp curr (a::l) = if gt(a,curr)
then lp a l
else lp curr l
in
lp
end
Run Code Online (Sandbox Code Playgroud)
有人可以帮忙解释一下这是做什么的吗?我最困惑的是这条线:
let fun lp curr [] = curr
Run Code Online (Sandbox Code Playgroud)
这到底是什么意思?据我所知,有一个函数叫lp但是这curr []意味着什么?这些论点?如果是这样,你不是只允许在sml中使用一个参数吗?
这意味着这lp是一个带有2个参数的函数,第一个是curr第二个,第二个是一个列表,在逻辑上,它可以是空的([])或包含至少一个元素((a::l)是列表的模式,a在头,其余的列表是l).
如果要将那些FP代码翻译成某种众所周知的命令式语言,它看起来像:
function lp(curr, lst) {
if (lst.length == 0) {
return curr;
} else {
var a = lst[0]; // first element
var l = lst.slice(1, lst.length); // the rest
if (gt(a, curr)) {
return lp(a, l);
} else {
return lp(curr, l)
}
}
}
Run Code Online (Sandbox Code Playgroud)
相当满口,但这是一个忠实的翻译.
函数语言基于Lambda微积分,其中函数只取一个值并返回一个结果.虽然SML和其他FP语言都是基于这种理论,但它在实践中相当不方便,因此许多这些语言允许您通过所谓的Currying将多个参数传递给函数.
所以是的,在ML函数中实际上只需要一个值,但currying可以让你模拟多个参数.
让我们创建一个名为的函数add,它会添加2个数字:
fun add a b = a + b
Run Code Online (Sandbox Code Playgroud)
应该这样做,但我们定义了2个参数.这是什么类型的add?如果你看看REPL,那就是val add = fn : int -> int -> int.其中读取"add是一个函数,它接受一个int并返回另一个函数(它接受一个int并返回一个int)"
所以我们也可以这样定义add:
fun add a =
fn b => a + b
Run Code Online (Sandbox Code Playgroud)
你会发现它们是相似的.事实上可以肯定地说,在某种程度上,前者是后者的语法糖.因此,您在ML中定义的所有函数,即使是具有多个参数的函数,实际上都是具有一个参数的函数,它返回接受第二个参数的函数,依此类推.起初有点难以适应,但很快就会成为第二天性.
fun add a b = a + b (* add is of type int -> int -> int *)
add 1 2 (* returns 3 as you expect *)
(* calling add with only one parameter *)
val add1 = add 1
Run Code Online (Sandbox Code Playgroud)
什么add1?这个函数会添加1到你传递的单个参数中!
add1 2 (* returns 3 *)
Run Code Online (Sandbox Code Playgroud)
这是部分应用程序的一个示例,您可以在其中逐个调用函数,一次调用一个参数,每次都返回,另一个函数接受其余参数.
此外,还有另一种方式来为外观的多个参数:元组:
(1, 2); (* evaluates to a tuple of (int,int) *)
fun add (a,b) = a + b;
add (1, 2) (* passing a SINGLE argument to a function that
expects only a single argument, a tuple of 2 numbers *)
Run Code Online (Sandbox Code Playgroud)
在你的问题中,lp 本来可以实现为lp (curr, someList):
fun max gt curr lst =
let fun lp (curr, []) = curr
| lp (curr, (a::l)) = if gt(a,curr) then lp (a, l)
else lp (curr, l)
in
lp (curr, lst)
end
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下,我们必须声明max为max gt curr lst!
在您发布的代码中,lp显然已经实现了currying.它的类型
max是fn: ('a * 'a -> bool) -> 'a -> 'a list -> 'a.把它分开:
('a * 'a -> bool) -> (* passed to 'max' as 'gt' *)
'a -> (* passed to 'lp' as 'curr' *)
'a list -> (* passed to 'lp' as 'someList' *)
'a (* what 'lp' returns (same as what 'max' itself returns) *)
Run Code Online (Sandbox Code Playgroud)
注类型的gt,第一个参数max:fn : (('a * 'a) -> bool)-它是一个功能一个说法('a * 'a),两元组'a的并返回一个'a.所以不要在这里讨好.
使用哪个是品味,惯例和实际考虑因素.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
988 次 |
| 最近记录: |