在OCaml中抑制穷举匹配警告 [英] Suppress exhaustive matching warning in OCaml

查看:114
本文介绍了在OCaml中抑制穷举匹配警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在修正OCaml编译器给我的警告时遇到问题。



基本上,我正在解析一个可由 Bool Int Float



我有一个符号表,用于跟踪所有用它们的类型声明的符号:

  type ast_type = Bool | Int | Float 
和variables =(string,int * ast_type)Hashtbl.t;

其中 int 是稍后使用的索引

然后我有一个具体的类型来表示变量中的值:

  type value = 
| BOOL bool
|整数int
| FLOAT浮动
| UNSET
和var_values =值数组

我试图定义一个变量的行为引用里面的布尔表达式,所以我做的是


  • 检查变量是否被声明

  • 检查该变量的类型为bool



这样做我有这个代码( s 是变量的名称):

  | GVar s  - > 
begin
try
let(i,t)= Hashtbl.find变量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

问题是我的检查保证来自 var_values 的元素的类型是 BOOL of bool ,但是当然这个约束不会被编译器警告我:


警告P:这种模式匹配并非详尽无遗。
这里是一个不匹配的值的示例:
(FLOAT _ | INT _ | UNSET)



<我该如何解决这类问题?在此先感谢

解决方案

这是一个可以使用 OCaml的多态变体



这里有一些可编译的我推断的OCaml代码展示了您的问题:

  type ast_type = Bool | Int | Float 
和variables =(string,int * ast_type)Hashtbl.t

type value =
| BOOL bool
|整数int
| FLOAT浮动
| UNSET

和var_values =值数组

类型expr =字符串$ G
$ b类型exceptioninfo = BoolExpected | VarUndefined
$ b $异常exceptioninfo的字符串异常* string

let variables = Hashtbl.create 13

let var_values = Array.create 13(BOOL false)

让fe =

|匹配GVar s - >
begin
try
let(i,t)= Hashtbl.find变量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

它会产生警告: p>

 文件t.ml,第30行,字符42-48:
警告P:此模式匹配不是无遗。
下面是一个不匹配的值的示例:
(FLOAT _ | INT _ | UNSET)

以下是使用多态变体转换的相同代码。该代码编译时没有警告。请注意,多态变量比标准类型具有更强大的表达能力(这里允许表达 var_values 是仅包含 BOOL 的数组),但它们会导致令人费解的警告。

  type ast_type = Bool | Int | Float 
和variables =(string,int * ast_type)Hashtbl.t

type value =
[`BOOL of bool
| INT
|的INT FLOAT浮动
| `UNSET]

和var_values =值数组
$ b $类型expr =字符串$ G $
$ b类型exceptioninfo = BoolExpected | VarUndefined
$ b $异常exceptioninfo *字符串的语义异常

let variables = Hashtbl.create 13

let var_values = Array.create 13(`BOOL false)

让fe =

|匹配GVar s - >
begin
try
let(i,t)= Hashtbl.find变量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

这是OCaml推断的类型在上面的代码中:

  type ast_type = Bool | Int | Float 
和variables =(string,int * ast_type)Hashtbl.t
type value = [`BOOL of bool | FLOAT浮动| INT的int | `UNSET]
和var_values =值数组
类型expr =字符串$ G的
类型exceptioninfo = BoolExpected | VarUndefined
异常exceptioninfo的字符串异常* string $ b $ val变量:(string,int * ast_type)Hashtbl.t $ b $ val var_values:[`BOOL of bool]数组
val f:expr - > 'a - > bool


I'm having a problem in fixing a warning that OCaml compiler gives to me.

Basically I'm parsing an expression that can be composed by Bool, Int and Float.

I have a symbol table that tracks all the symbols declared with their type:

type ast_type = Bool | Int | Float
and variables = (string, int*ast_type) Hashtbl.t;

where int is the index used later in the array of all variables.

I have then a concrete type representing the value in a variable:

type value =
  | BOOL of bool
  | INT of int
  | FLOAT of float
  | UNSET
and var_values = value array

I'm trying to define the behaviour of a variable reference inside a boolean expression so what I do is

  • check that the variable is declared
  • check that the variable has type bool

to do this I have this code (s is the name of the variable):

| 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

The problem is that my checks assure that the element taken from var_values will be of type BOOL of bool but of course this constraint isn't seen by the compiler that warns me:

Warning P: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: (FLOAT _ |INT _ |UNSET)

How am I supposed to solve this kind of issues? Thanks in advance

解决方案

This is a problem that you can solve using OCaml's polymorphic variants.

Here is some compilable OCaml code that I infer exhibits your problem:

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

It generates the warning:

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)

Here is the same code transformed to use polymorphic variants. That code compiles without warnings. Note that polymorphic variants have more expressive power than standard types (here allowing to express that var_values is an array of BOOL only), but they can lead to puzzling warnings.

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

Here are the types inferred by OCaml on the above code:

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

这篇关于在OCaml中抑制穷举匹配警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆