exception - OCaml,了解错误消息
问题描述
let rec smallest l =
match l with
| [] -> raise Not_found
| [a] -> (fun x -> if x > 0 then x else raise Not_found) a
| h::b::t ->
if h > b then smallest h::t
else smallest b::t`
如果列表中存在正整数,则此函数假定采用int list
并返回最小值,如果列表中没有正整数,则int
引发异常。Not_found
当我尝试这个时,我得到以下错误,smallest h::t
在第三个匹配模式中找到了下划线:
错误:此表达式具有类型
'a list
,但表达式应为类型int
有人可以向我解释我做错了什么吗?
解决方案
smallest h::t
相当于(smallest h)::t
。也就是说,它适用smallest
于参数h
,然后将其添加到 list t
。这使 OCaml 抱怨说,当您应该生成一个整数时,您正在生成一个列表。你想要的是smallest (h::t)
.
该函数假设获取一个 int 列表,如果列表中有一个正整数,则返回最小的 int;如果列表中没有正整数,则引发异常 Not_found。
即使使用上述修复程序,该功能也不会这样做。相反,如果至少有一个正元素,它将在列表中找到最大的元素。那是因为你总是在你的if
. 如果您切换它,以便它始终采用较小的元素,那么只要列表中至少有一个非正元素,它就会失败。
解决这个问题的一种方法是只选择一个元素作为列表的新头,如果它是正的并且小于当前的头,或者它是正的并且当前的头是负的。
然而,获得与您的描述匹配的函数的另一种可能更简洁的方法是首先定义一个函数,该函数从任何非空列表中取出最小元素(忽略它是否为正),然后定义另一个调用第一个函数的函数过滤列表以仅包含正面元素后的功能。像这样:
let smallest_positive xs = smallest (List.filter (fun x -> x > 0) xs)
PS:这与您的问题无关,但以下表达式看起来很奇怪:
(fun x -> if x > 0 then x else raise Not_found) a
在 OCaml 中通常很少有理由创建一个函数来立即应用它——这只是一种更复杂的编写let
表达式的方式,在这种情况下你甚至不需要let
. 换句话说,以上等价于:
let x = a in
if x > 0 then x else raise Not_found
这又相当于:
if a > 0 then a else raise Not_found
推荐阅读
- node.js - node js await 似乎没有等待
- android - Android服务引起的替换通知
- ios - 屏幕截图大小错误
- javascript - getFiles 和 getFolders 总是只返回一个文件/文件夹
- apache-nifi - NiFi - 连接到另一个实例(S2S)
- mysql - 仅在插入新行时设置 current_timestamp
- docker - 在 docker 环境中通过 OWASP zap 扫描 Rest API
- asp.net - 如何将文件夹发布到 Azure 应用服务?
- typescript - 使用 TypeScript Compiler API 获取 TypeScript 节点的字符串表示
- netsuite - 是否可以在不必加载整个记录的情况下获取行项目的值?