ocaml - OCaml 断言失败
问题描述
大家好,我是 OCaml 的新手,遇到了一些问题。所以我试图做一个递归函数,它接受一个非空列表并返回最后一个元素。我的列表可以是任何数据类型。这是我现在所拥有的,它目前在断言语句中失败,说“这个表达式的类型是 int,但表达式应该是 int 类型的列表。
let rec last l = match l with
[] -> []
|[x] -> [x]
|_::t -> last t ;;
assert(last [1; 2; 3; 4] = 4);;
assert(last ["a"; "b"; "c"; "d"] = "d");;
解决方案
我经常发现处理这种类型错误的一个好方法是用我希望它具有的类型显式注释函数 - 在这种情况下,我希望你希望第一行是这样的:
let rec last: 'a list -> 'a = fun l -> match l with
这样,错误变为:
File "1/hest.ml", line 5, characters 9-10:
5 | |[x] -> [x]
^
Error: This expression has type 'a list
but an expression was expected of type 'a
The type variable 'a occurs inside 'a list
这是一个更有帮助的错误。问题是,正如@PatJ 在他的回答中所写,当您编写函数时,您实际上返回了一个包含一个元素的列表(或没有元素,当列表为空时),但您对该函数的使用似乎表明您只想要最后一个元素。
您可以:
- 更改函数的用法,因此断言与值进行比较,
[4]
而["d"]
不仅仅是值。 - 将函数更改为返回
Some x
andNone
而不是[x]
and[]
,并将断言更改为针对Some 1
and进行断言Some "d"
。 - 将函数更改为 return
x
而不是[x]
并在空列表情况下引发异常 - 那将是:failwith "empty list"
我认为第二种解决方案是最自然的。
如果您选择异常,则将函数重命名为last_exn
将向用户传达他们必须注意函数可能会抛出的信息。
推荐阅读
- javascript - 如何在 angular-flot 条上添加 onclick 功能
- node.js - 将变量传递给views子文件夹中的ejs模板文件
- python - ValueError:折叠数必须是 Integral 类型。[数组([[0.25, 0.
- html - 响应式图片弹性库
- oracle - 如何使用 Oracle.jl 删除 oracle 表?
- php - 如何检查日期('H:i:s')是否大于夜间时间且小于一天的开始时间?
- node.js - 错误:在谷歌应用引擎上部署节点 js 时找不到模块“/workspace/server.js”
- python - Python 3 请求如何强制为每个请求使用新连接?
- javascript - Jquery On Scroll Video Play n Pause 不适用于 Jquery“加载更多”内容
- flutter - 未注册的视图类型:'plugins.endigo.io/pdfview',null)