我不知道为什么我的代码不起作用。
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
答案 0 :(得分:4)
您的代码没有任何问题,您只是没有用足够的参数调用lookup
。你在来自其他语言的初学者SML程序员中犯了一个常见的错误。我试着澄清一下。
首先,了解标准ML中最重要的功能是:
标准ML中的所有函数只接受一个参数。
此时您可能会感到困惑,因为您的lookup
函数看起来好像有两个参数。它确实有,但不是真的。
有两个主要的解决方案" (我使用引号,因为这实际上是语言的一个很棒的特性),用于表示带有多个参数的函数:
如果你需要编写一个在概念上需要三个参数的函数,那么你就写下这个:
fun quux a =
fn b =>
fn c =>
(* do something with a, b and c *)
所以,quux
是:
a
并返回b
并返回c
并返回a
,b
和c
您如何致电quux
?像这样,对吧?
((quux a) b) c
但是函数应用程序已经是关联的,所以我们实际上可以这样写:
quux a b c
我们不需要括号来打电话"功能!在标准ML括号中,并不意味着将此功能称为“#34;”。当您想要更改关联性时,它们仅用于将表达式组合在一起,例如数学:(1 + 2) * 3
。
因为如上所述定义quux
非常麻烦,所以语言中有一个句法快捷方式。而不是写这个:
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
的新函数。
好的,这是在Standard ML中表示多参数函数的一种方法。它也是您用来定义lookup
的那个。
表示多参数函数的另一种常用方法是接受一个元组(可能有2到任意数量的组件)。以上是使用元组的上述示例:
fun quux args =
case args of
(a,b,c) => (* do something with a, b and c *)
我们现在怎么称呼quux
?像这样:
quux (a,b,c)
请注意,我在quux
和元组之间放了一个空格。它是可选的,但是我一直这样做是为了记住标准ML中的函数应用程序是而不是用括号表示。 quux
被调用,因为它被放在元组(a,b,c)
之前。但是,元组确实需要括号,这就是你在上面看到它们的原因。
同样,和以前一样,定义quux
这样很麻烦:
fun quux args =
case args of
(a,b,c) => (* do something with a, b and c *)
所以我们实际上可以使用语言的另一个很棒的特性,在参数位置进行模式匹配,这让我们写下这个:
fun quux (a,b,c) = (* do something with a, b and c *)
好的,现在我们可以回答你的问题了。
您使用curried函数语法定义lookup
:
fun lookup _ [] = 0
但你"叫" lookup
使用元组语法,其中1
是元组的第一个元素,[(1,2),(2,3)]
是第二个元素。
lookup (1, [(1,2),(2,3)])
但是为什么编译器没有抱怨。在这个不幸的情况下,它并不是因为它发生了查找的第一个参数的类型是一个元组。所以,你基本上只用一个参数调用lookup
。
你想要的是:
lookup 1 [(1,2),(2,3)]
请注意,我不再定义元组。