我的sml代码有什么问题?

我的sml代码有什么问题?,sml,Sml,我不知道为什么我的代码不起作用 fun lookup _ [] = 0 | lookup key ((k,v)::entries) = if k = key then v else (lookup key entries) 这就是我在cmd中测试它时发生的情况 val lookup = fn : ''a -> (''a * int) list -> int - lookup (1,[(1,2),(2,3)]); val it = fn : ((int *

我不知道为什么我的代码不起作用

fun lookup _ [] = 0
  | lookup key ((k,v)::entries) =
    if k = key
    then v
    else (lookup key entries)
这就是我在cmd中测试它时发生的情况

val lookup = fn : ''a -> (''a * int) list -> int
- lookup (1,[(1,2),(2,3)]);
val it = fn : ((int * (int * int) list) * int) list -> int

您的代码没有问题,只是没有使用足够的参数调用
lookup
。在来自其他语言的SML程序员中,您会犯一个常见的错误。我将试图澄清这一点

首先,了解标准ML中的函数最重要的是:

标准ML中的所有函数只取一个参数

此时您可能会感到困惑,因为您的
lookup
函数看起来好像包含两个参数。有点像,但不是真的

对于表示具有多个参数的函数,有两种主要的“变通方法”(我使用引号,因为这实际上是该语言的一个重要特性):

1.使用curried函数 如果您需要编写一个概念上需要三个参数的函数,那么您可以编写以下内容:

fun quux a =
  fn b =>
    fn c =>
      (* do something with a, b and c *)
quux a b c
fun quux (a,b,c) = (* do something with a, b and c *)
所以,
qux
是:

  • 一种函数,它接受一个参数
    a
    并返回
  • 一个函数,它接受一个参数
    b
    并返回
  • 一个函数,它接受一个参数
    c
    并返回
  • 使用
    a
    b
    c
您将如何调用
quox
?像这样,对吗

((quux a) b) c
但函数应用程序已经是左关联的,因此我们可以实际编写:

fun quux a =
  fn b =>
    fn c =>
      (* do something with a, b and c *)
quux a b c
fun quux (a,b,c) = (* do something with a, b and c *)
我们不需要括号来“调用”函数!在标准ML中,括号并不表示“调用此函数”。它们仅用于在需要更改关联性时将表达式分组在一起,如在数学中:
(1+2)*3

由于如上定义
qux
非常麻烦,因此该语言中有一个语法快捷方式。而不是写这封信:

fun quux a =
  fn b =>
    fn c =>
      (* do something with a, b and c *)
我们可以这样写:

fun quux a b c = (* do something with a, b and c *)
但是,它们是一样的
quux
仍然是一个只接受参数
a
并返回一个带有参数
b
的新函数的函数,该函数返回一个带有参数
c
的新函数

好的,这是在标准ML中表示多参数函数的一种方法。它也是您用来定义
查找
的方法

2.使用元组 表示多参数函数的另一种常见方法是接受一个元组(可能有2到任意多个组件)。下面是上面使用元组的示例:

fun quux args =
  case args of
    (a,b,c) => (* do something with a, b and c *)
我们现在怎么能调用
qux
?像这样:

quux (a,b,c)
注意,我在
qux
和元组之间放置了一个空格。它是可选的,但我一直都在这样做,以记住标准ML中的函数应用程序不是用括号表示的<代码>qux被调用,因为它已放在元组之前
(a、b、c)
。然而,元组确实需要括号,这就是为什么您在上面看到它们

同样,像以前一样,像这样定义
qux
很麻烦:

fun quux args =
  case args of
    (a,b,c) => (* do something with a, b and c *)
所以我们实际上可以使用语言的另一个重要特性,参数位置的模式匹配,这让我们可以写下:

fun quux a =
  fn b =>
    fn c =>
      (* do something with a, b and c *)
quux a b c
fun quux (a,b,c) = (* do something with a, b and c *)
好的,现在我们可以回答你的问题了


您使用当前函数语法定义了
lookup

fun lookup _ [] = 0
但是您使用元组语法“调用”
lookup
,其中
1
是元组的第一个元素,
[(1,2)、(2,3)]
是第二个元素

lookup (1, [(1,2),(2,3)])
不过,编译器为什么不抱怨呢。在这种不幸的情况下,情况并非如此,因为查找的第一个参数的类型恰好是元组。因此,您基本上用一个参数调用了
lookup

你想要的是:

lookup 1 [(1,2),(2,3)]

请注意,我不再定义元组了。

您的代码没有问题,只是没有使用足够的参数调用
lookup
。在来自其他语言的SML程序员中,您会犯一个常见的错误。我将试图澄清这一点

首先,了解标准ML中的函数最重要的是:

标准ML中的所有函数只取一个参数

此时您可能会感到困惑,因为您的
lookup
函数看起来好像包含两个参数。有点像,但不是真的

对于表示具有多个参数的函数,有两种主要的“变通方法”(我使用引号,因为这实际上是该语言的一个重要特性):

1.使用curried函数 如果您需要编写一个概念上需要三个参数的函数,那么您可以编写以下内容:

fun quux a =
  fn b =>
    fn c =>
      (* do something with a, b and c *)
quux a b c
fun quux (a,b,c) = (* do something with a, b and c *)
所以,
qux
是:

  • 一种函数,它接受一个参数
    a
    并返回
  • 一个函数,它接受一个参数
    b
    并返回
  • 一个函数,它接受一个参数
    c
    并返回
  • 使用
    a
    b
    c
您将如何调用
quox
?像这样,对吗

((quux a) b) c
但函数应用程序已经是左关联的,因此我们可以实际编写:

fun quux a =
  fn b =>
    fn c =>
      (* do something with a, b and c *)
quux a b c
fun quux (a,b,c) = (* do something with a, b and c *)
我们不需要括号来“调用”函数!在标准ML中,括号并不表示“调用此函数”。它们仅用于在需要更改关联性时将表达式分组在一起,如在数学中:
(1+2)*3

由于如上定义
qux
非常麻烦,因此该语言中有一个语法快捷方式。而不是写这封信:

fun quux a =
  fn b =>
    fn c =>
      (* do something with a, b and c *)
我们可以这样写:

fun quux a b c = (* do something with a, b and c *)
但是,它们是一样的
quux
仍然是一个只接受参数
a
并返回一个带有参数
b
的新函数的函数,该函数返回一个带有参数
c
的新函数

好的,这是在标准ML中表示多参数函数的一种方法。它也是您用来定义
查找
的方法

2.使用元组 表示mul的另一种常见方式