这个函数签名在sml中意味着什么? [英] What does this function signature mean in sml?

查看:124
本文介绍了这个函数签名在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆