递归列表创建函数。类型错误

4

我有一个 Ocaml 函数,出现了错误。

我的目标是:

递归地创建一个大小为“limit”的随机数列表(范围在0-2之间)。

这是我的代码:

let rec carDoorNumbers = fun limit -> 
match limit with
| [1] -> Random.int 3
| [] -> Random.int 3 :: carDoorNumbers (limit-1);;

我正在遇到这个错误:
Error: This expression has type 'a list
   but an expression was expected of type int
2个回答

3

考虑你的函数需要做什么:给出一个限制,你需要创建一个数字的列表。所以你的类型类似于carDoorNumbers: int -> int list

看起来你有两个错误。首先,你将limit(应该是一个int)与列表模式进行匹配。 [1] -> ...匹配只包含元素1的列表和[]匹配空列表;你真正想要的是匹配数1和任何其他数n

第二个错误是你在match语句中返回了两种不同的类型。记住,你应该返回一个列表。在第一种情况下,你返回了一个Random.int 3,这是一个int而不是int list,你真正想要返回的是类似于[Random.int 3]的东西。

你得到的错误有点困惑。因为你返回的第一件事是一个int,它期望你的第二件事也是一个int。然而,你的第二个情况实际上是正确的:你确实返回了一个int list!但是,编译器不知道你的意思,所以它的错误是反向的;而不是将int list更改为int,你需要将int更改为int list


好的,那很有道理。对于我的第二种情况,我应该如何将其用于所有其他限制可能性,而不是与空列表[]进行比较(我假设它是一个正数#)? - Joshua Soileau
参数是一个数字。您想匹配任何数字(除了1,但它已经被前面的情况匹配了)。您可以使用最简单的模式n来实现这一点,它匹配任何内容并将其绑定到变量n。(您可以自然地为变量命名任何您想要的名称。) - Tikhon Jelvis

2
你的match表达式把limit当作列表处理。 [1][]都是列表。这就是编译器告诉你的。但是,看起来limit应该是一个整数。
要匹配一个整数,只需使用一个整数常量,不需要方括号。
(顺便说一句,当你传递0时,你可能希望确保函数能够正常工作。)

是的,我肯定没有考虑到所有的输入情况,假设为正整数。谢谢,我会去掉括号。我怎样才能使第二种情况在除了1以外的每个“限制”下运行? 我越想越觉得我需要if/else语句。 - Joshua Soileau
1
“通配符”模式是“_”,这对于此代码有效。在OCaml中使用“if/then/else”没有任何害处。这是我通常用于整数的方法。 - Jeffrey Scofield

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接