Jac*_*ack 10 warnings ocaml functional-programming pattern-matching
我在修复OCaml编译器给我的警告方面遇到了问题.
基本上我解析可以由组成的表达式Bool,Int和Float.
我有一个符号表,跟踪用其类型声明的所有符号:
type ast_type = Bool | Int | Float
and variables = (string, int*ast_type) Hashtbl.t;
Run Code Online (Sandbox Code Playgroud)
int后面在所有变量数组中使用的索引在哪里.
然后我有一个表示变量值的具体类型:
type value =
| BOOL of bool
| INT of int
| FLOAT of float
| UNSET
and var_values = value array
Run Code Online (Sandbox Code Playgroud)
我试图在布尔表达式中定义变量引用的行为,所以我要做的是
要做到这一点,我有这个代码(s是变量的名称):
| GVar s ->
begin
try
let (i,t) = Hashtbl.find variables s in
if (t != Bool) then
raise (SemanticException (BoolExpected,s))
else
(fun s -> let BOOL v = Array.get var_values i in v)
with
Not_found -> raise (SemanticException (VarUndefined,s))
end
Run Code Online (Sandbox Code Playgroud)
问题是我的检查确保取出的元素var_values是类型的,BOOL of bool但当然编译器没有看到这个约束警告我:
警告P:此模式匹配并非详尽无遗.以下是不匹配的值的示例:(FLOAT _ | INT _ | UNSET)
我该如何解决这类问题?提前致谢
这是一个可以使用OCaml的多态变体解决的问题.
这里有一些可编译的OCaml代码我推断出你的问题:
type ast_type = Bool | Int | Float
and variables = (string, int*ast_type) Hashtbl.t
type value =
| BOOL of bool
| INT of int
| FLOAT of float
| UNSET
and var_values = value array
type expr = GVar of string
type exceptioninfo = BoolExpected | VarUndefined
exception SemanticException of exceptioninfo * string
let variables = Hashtbl.create 13
let var_values = Array.create 13 (BOOL false)
let f e =
match e with
| GVar s ->
begin
try
let (i,t) = Hashtbl.find variables s in
if (t != Bool) then
raise (SemanticException (BoolExpected,s))
else
(fun s -> let BOOL v = Array.get var_values i in v)
with
Not_found -> raise (SemanticException (VarUndefined,s))
end
Run Code Online (Sandbox Code Playgroud)
它会生成警告:
File "t.ml", line 30, characters 42-48:
Warning P: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
(FLOAT _|INT _|UNSET)
Run Code Online (Sandbox Code Playgroud)
以下是转换为使用多态变体的相同代码.该代码编译时没有警告.请注意,多态变体比标准类型具有更强的表达能力(这里允许表示var_values只是一个数组BOOL),但它们可能会导致令人费解的警告.
type ast_type = Bool | Int | Float
and variables = (string, int*ast_type) Hashtbl.t
type value =
[ `BOOL of bool
| `INT of int
| `FLOAT of float
| `UNSET ]
and var_values = value array
type expr = GVar of string
type exceptioninfo = BoolExpected | VarUndefined
exception SemanticException of exceptioninfo * string
let variables = Hashtbl.create 13
let var_values = Array.create 13 (`BOOL false)
let f e =
match e with
| GVar s ->
begin
try
let (i,t) = Hashtbl.find variables s in
if (t != Bool) then
raise (SemanticException (BoolExpected,s))
else
(fun s -> let `BOOL v = Array.get var_values i in v)
with
Not_found -> raise (SemanticException (VarUndefined,s))
end
Run Code Online (Sandbox Code Playgroud)
以下是OCaml在上述代码中推断出的类型:
type ast_type = Bool | Int | Float
and variables = (string, int * ast_type) Hashtbl.t
type value = [ `BOOL of bool | `FLOAT of float | `INT of int | `UNSET ]
and var_values = value array
type expr = GVar of string
type exceptioninfo = BoolExpected | VarUndefined
exception SemanticException of exceptioninfo * string
val variables : (string, int * ast_type) Hashtbl.t
val var_values : [ `BOOL of bool ] array
val f : expr -> 'a -> bool
Run Code Online (Sandbox Code Playgroud)