OCaml错误中的逻辑操作
我试图用OCaml编写一个函数来解决逻辑运算。这一尝试是成功的:OCaml错误中的逻辑操作,ocaml,Ocaml,我试图用OCaml编写一个函数来解决逻辑运算。这一尝试是成功的: let rec tf =function |B b->b |V s->failwith "not good" |And(e1,e2)->tf e1&&tf e2 |Or(e1,e2)->tf e1||tf e2 |Neg b-> not (tf b);; 但当我编写以下函数时,程序会警告我一些错误: type bv = B of bool | V of strin
let rec tf =function
|B b->b
|V s->failwith "not good"
|And(e1,e2)->tf e1&&tf e2
|Or(e1,e2)->tf e1||tf e2
|Neg b-> not (tf b);;
但当我编写以下函数时,程序会警告我一些错误:
type bv = B of bool | V of string | Neg of bv
| And of bv * bv | Or of bv * bv;;
module MS=Map.Make(String);;
let prop x map=
let rec aux=function
|B b->b
|Neg b-> not (aux b)
|V s->try aux(B (MS.find s map)) with Not_found->failwith ""
|And(e1,e2)->aux e1&&aux e2
|Or(e1,e2)->aux e1||aux e2
in aux x;;
Characters 145-148:
|And(e1,e2)->aux e1&&aux e2
^^^
Error: This variant pattern is expected to have type exn
The constructor And does not belong to type exn
其中map是(string*bool)map。如果函数的参数“x”是一个字符串,那么它将在映射中查找它并获得布尔值,然后在进一步的演算中使用它。如果找不到x,它将抛出异常并结束函数。
我知道这与VS匹配有关,但我不知道这里出了什么问题让我展示一下,知道OCaml语法的压头是如何缩进代码的:
let prop x map=
let rec aux=function
|B b->b
|Neg b-> not (aux b)
|V s->try aux(B (MS.find s map)) with Not_found->failwith ""
| And(e1,e2)->aux e1&&aux e2
| Or(e1,e2)->aux e1||aux e2
in aux x;;
现在,很明显,为什么和
和或
被认为是例外
您可以将呼叫插入aux,例如
let prop x map =
let rec aux=function
|B b->b
|Neg b-> not (aux b)
|V s-> (try aux(B (MS.find s map)) with Not_found->failwith "")
|And(e1,e2)->aux e1&&aux e2
|Or(e1,e2)->aux e1||aux e2
in aux x;;
但是,在每个递归调用周围安装异常处理程序并不是一个好主意,因为这会导致在堆栈上安装N
异常记录,从而破坏尾部递归的思想。最好按照以下方式重写算法:
let prop x map=
let rec aux=function
|B b->b
|Neg b-> not (aux b)
|V s when MS.mem s map -> aux (B (MS.find s map))
|V s -> invalid_arg ("Unbound variable: " ^ s)
|And(e1,e2) -> aux e1&&aux e2
|Or(e1,e2) -> aux e1||aux e2 in
aux x
让我演示一下,了解OCaml语法的压头将如何缩进代码:
let prop x map=
let rec aux=function
|B b->b
|Neg b-> not (aux b)
|V s->try aux(B (MS.find s map)) with Not_found->failwith ""
| And(e1,e2)->aux e1&&aux e2
| Or(e1,e2)->aux e1||aux e2
in aux x;;
现在,很明显,为什么和
和或
被认为是例外
您可以将呼叫插入aux,例如
let prop x map =
let rec aux=function
|B b->b
|Neg b-> not (aux b)
|V s-> (try aux(B (MS.find s map)) with Not_found->failwith "")
|And(e1,e2)->aux e1&&aux e2
|Or(e1,e2)->aux e1||aux e2
in aux x;;
但是,在每个递归调用周围安装异常处理程序并不是一个好主意,因为这会导致在堆栈上安装N
异常记录,从而破坏尾部递归的思想。最好按照以下方式重写算法:
let prop x map=
let rec aux=function
|B b->b
|Neg b-> not (aux b)
|V s when MS.mem s map -> aux (B (MS.find s map))
|V s -> invalid_arg ("Unbound variable: " ^ s)
|And(e1,e2) -> aux e1&&aux e2
|Or(e1,e2) -> aux e1||aux e2 in
aux x