Exception OCaml,理解错误消息

Exception OCaml,理解错误消息,exception,types,error-handling,pattern-matching,ocaml,Exception,Types,Error Handling,Pattern Matching,Ocaml,假设此函数获取一个int列表,如果列表中有正整数,则返回最小的int,如果列表中没有正整数,则引发异常Not\u found 当我尝试此操作时,我在第三个带下划线的匹配模式中发现最小h::t时出现以下错误: 错误:此表达式具有类型'a列表 但表达式的类型应为int 有人能解释一下我做错了什么吗?最小的h::t相当于(最小的h)::t。也就是说,它将最小值应用于参数h,然后将其前置到列表t。这使得OCaml抱怨说,当您应该生成一个整数时,您正在生成一个列表。您想要的是最小的(h::t) 假设此函数

假设此函数获取一个
int列表
,如果列表中有正整数,则返回最小的
int
,如果列表中没有正整数,则引发异常
Not\u found

当我尝试此操作时,我在第三个带下划线的匹配模式中发现
最小h::t
时出现以下错误:

错误:此表达式具有类型
'a列表
但表达式的类型应为
int


有人能解释一下我做错了什么吗?

最小的h::t
相当于
(最小的h)::t
。也就是说,它将
最小值
应用于参数
h
,然后将其前置到列表
t
。这使得OCaml抱怨说,当您应该生成一个整数时,您正在生成一个列表。您想要的是
最小的(h::t)

假设此函数获取一个int列表,如果列表中有正整数,则返回最小的int;如果列表中没有正整数,则引发异常Not_found

即使使用上述修复,函数也不会这样做。相反,如果至少有一个正元素,它将查找列表中最大的元素。这是因为您总是在
if
中选择较大的元素。如果您切换它,使它总是使用较小的元素,那么每当列表中至少有一个非正元素时,它就会失败

解决此问题的一种方法是,如果元素为正且小于当前标头,或者元素为正且当前标头为负,则仅选择元素作为列表的新标头

然而,获得与您的描述匹配的函数的另一种可能更简洁的方法是,首先定义一个函数,从任何非空列表中取出最小的元素(忽略它是否为正),然后定义另一个函数,在过滤列表后调用第一个函数,以仅包含正元素。像这样:

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`

PS:这与您的问题无关,但以下表达式看起来很奇怪:

let smallest_positive xs = smallest (List.filter (fun x -> x > 0) xs)
在OCaml中,通常很少有理由创建一个函数来立即应用它——这只是编写
let
表达式的一种更复杂的方法,在这种情况下,您甚至不需要
let
。换言之,上述内容相当于:

(fun x -> if x > 0 then x else raise Not_found) a
let x = a in
if x > 0 then x else raise Not_found
这反过来相当于:

(fun x -> if x > 0 then x else raise Not_found) a
let x = a in
if x > 0 then x else raise Not_found

经过深思熟虑,我终于能够回答我自己的问题了

if a > 0 then a else raise Not_found
让rec最小=
匹配
|[]->未找到提升
|[a]->(乐趣x->如果x>0,则x未找到其他提升)a
|h::b::t->
如果h0
然后最小(h::t)
其他最小值(b::t)`

@JunghwanOh抱歉,那是个打字错误。