- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在查看我的教授关于 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
有人可以帮忙解释一下这是在做什么吗?我最困惑的是这行:
let fun lp curr [] = curr
这到底是什么意思?据我所知,有一个名为 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)
}
}
}
虽然拗口,但翻译很忠实。
函数式语言基于 Lambda Calculus ,其中函数仅采用一个值并返回一个结果。虽然 SML 和其他 FP 语言基于此理论,但在实践中相当不方便,因此许多这些语言允许您通过所谓的 Currying 来表达将多个参数传递给函数。 .
所以,是的,在 ML 函数中实际上只采用一个值,但柯里化(Currying)可以让您模拟多个参数。
让我们创建一个名为 add
的函数,它将 2 个数字相加:
fun add a b = a + b
应该可以,但是我们定义了 2 个参数。 add
的类型是什么?如果你看一下 REPL,它是 val add = fn : int -> int -> int
。其中写道,“add 是一个接受 int 并返回另一个函数(接受 int 并返回 int)的函数”
所以我们也可以这样定义add
:
fun add a =
fn b => a + b
你会发现它们很相似。事实上,在某种程度上可以肯定地说,前者是后者的语法糖。因此,您在 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
什么是add1
?这是一个函数,它将向您传递的单个参数添加1
!
add1 2 (* returns 3 *)
这是一个部分应用的示例,您可以在其中逐步调用函数,一次一个参数,每次返回,另一个函数接受其余参数论据。
此外,还有另一种方式给出多个参数的外观:元组:
(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 *)
在您的问题中,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
请注意,在这种情况下,我们必须将 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) *)
注意 gt
的类型,即 max
的第一个参数:fn : (('a * 'a) -> bool)
- 它是一个参数('a * 'a)
的函数,两个'a
的元组's 并且它返回一个 'a
。所以这里没有柯里化(Currying)。
使用哪个是品味、惯例和实际考虑的问题。
希望这有帮助。
关于function - 这个函数签名在sml中是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14432696/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!