这个函数签名在sml中意味着什么? [英] What does this function signature mean in sml?
问题描述
> fun max gt =
让乐趣lp curr [] = curr
| lp curr(a :: l)= if gt(a,curr)
然后lp al
else lp curr l
in
lp
end
有人可以帮忙解释这是干什么吗?我最困惑的事情是行:
let fun lp curr [] = curr
code>
这到底意味着什么?据我所知,有一个名为 lp
的函数,但是 curr []
是什么意思?这些论据是?如果是这样,是不是只允许在sml中有一个参数?
这意味着 lp
是一个接受2个参数的函数,第一个参数是 curr
,第二个参数是一个列表,逻辑上它可以是空的( []
)或至少包含一个元素((a :: l)
是一个列表模式其中 a
位于头部,其余部分为 l
)。
如果有人将这段FP代码翻译成某种众所周知的命令式语言,它看起来像:
函数lp(curr,lst){
if(lst.length == 0){
return curr;
} else {
var a = lst [0]; //第一个元素
var l = lst.slice(1,lst.length); //其余
if(gt(a,curr)){
return lp(a,l);
} else {
return lp(curr,l)
}
}
}
功能语言基于 Lambda微积分,其中函数只需要一个值并返回一个结果。虽然SML和其他FP语言是基于这个理论的,但在实践中这很不方便,所以这些语言中的很多都允许你通过所谓的 Currying 。
所以,是的,ML函数实际上只有一个值,但currying允许你模拟多个参数。 / p>
让我们创建一个名为 add
的函数,它添加了2个数字:
fun add ab = 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 ab = a * b *(* add的类型是int - > int - > int *)
add 1 2(*返回3,如您期望的*)
调用add只有一个参数*)
val add1 = add 1
什么是 add1
?这是一个功能,它会将 1
添加到您传递它的单个参数中!
add1 2(*返回3 *)
这是 partial application 的例子,你在这里调用一个零碎的函数,
一次一个参数,每次返回一个函数,接受其余
的参数。 / p>
另外,还有另一种方法可以给出多个参数的外观:元组:
(1,2); (*评估为(int,int)*的元组)
fun add(a,b)= a + b;
add(1,2)(*传递一个SINGLE参数给一个函数,
只需要一个参数,一个包含2个数字的元组* *)
在您的问题中, lp
也可以实现作为 lp(curr,someList)
:
fun max gt curr lst =
让乐趣lp(curr,[])= curr
| lp(curr,(a :: l))= if gt(a,curr)然后lp(a,l)
else $ l
$ curl, lst)
end
请注意,在这种情况下,我们必须声明 max
作为 max gt curr lst
!
在您发布的代码中, lp
显然是用柯里化来实现的。而
max
本身的类型是 fn:('a *'a - > bool) - > 'a - > '列表 - > 一
。除此之外:
('a *'a - > bool) - > (*作为'gt'传递给'max'*)
'a - > (*作为'curr'*)传递给'lp'
'列表 - > (*作为'someList'*)传递给'lp')
'a(* what'lp'returns(与'max'本身返回的相同)*)
请注意 gt
的类型,它是<$ c的第一个参数$ c> max : fn:(('a *'a) - > bool)
- 它是 参数('a *'a)
,一个包含两个'a
'的元组,它返回一个'a
。所以不要在这里喝咖啡。
使用哪一个是品味,惯例和实际考虑的问题。
希望这有助于。
I'm looking through some notes that my professor gave regarding the language SML and one of the functions looks like this:
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
Could someone help explain what this is doing? The thing that I am most confused about is the line:
let fun lp curr [] = curr
What exactly does this mean? As far as I can tell there is a function called lp
but what does the curr []
mean? Are these arguments? If so, aren't you only allowed one parameter in sml?
It means that lp
is a function that takes 2 parameters, the first being curr
and the second being, well, a list, which logically, may be either empty ([]
) or contain at least one element ((a::l)
is a pattern for a list where a
is at the head, and the rest of the list is l
).
If one were to translate that bit of FP code into a certain well-known imperative language, it would look like:
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)
}
}
}
Quite a mouthful, but it's a faithful translation.
Functional languages are based on the Lambda Calculus, where functions take exactly one value and return one result. While SML and other FP languages are based on this theory, it's rather inconvenient in practice, so many of these languages allow you to express passing multiple parameters to a function via what is known as Currying.
So yes, in ML functions actually take only one value, but currying lets you emulate multiple arguments.
Let's create a function called add
, which adds 2 numbers:
fun add a b = a + b
should do it, but we defined 2 parameters. What's the type of add
? If you take a look in the REPL, it is val add = fn : int -> int -> int
. Which reads, "add is a function that takes an int and returns another function (which takes an int and returns an int)"
So we could also have defined add
this way:
fun add a =
fn b => a + b
And you will see that they are alike. In fact it is safe to say that in a way, the former is syntactic sugar for the later. So all functions you define in ML, even those with several arguments, are actually functions with one argument, that return functions that accept the second argument and so on. It's a little hard to get used to at first but it becomes second nature very soon.
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
What's add1
? It is a function that will add 1
to the single argument you pass it!
add1 2 (* returns 3 *)
This is an example of partial application, where you are calling a function piecemeal, one argument at a time, getting back each time, another function that accepts the rest of the arguments.
Also, there's another way to give the appearance of multiple arguments: tuples:
(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 *)
In your question, lp
could have also been implemented as 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
Note that in this case, we have to declare max
as max gt curr lst
!
In the code you posted, lp
was clearly implemented with currying. And the type of
max
itself was fn: ('a * 'a -> bool) -> 'a -> 'a list -> 'a
. Taking that apart:
('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) *)
Note the type of gt
, the first argument to max
: fn : (('a * 'a) -> bool)
- it is a function of one argument ('a * 'a)
, a tuple of two 'a
's and it returns an 'a
. So no currying here.
Which to use is a matter of both taste, convention and practical considerations.
Hope this helps.
这篇关于这个函数签名在sml中意味着什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!