我目前正在构建一个项目,它允许不同类型的函数,具有不同数量的参数(但它们都是相同类型的)。为了定义这些函数,我为每个函数使用了这个代码:
let {name} [a; b; {...}] =
{...}
我的代码确保列表中的元素数量是正确的,如果不是这种情况,我只会发生运行时错误。但我有一个警告,我想要隐藏,因为我知道这种模式匹配并非详尽无遗,而且我不希望看到警告不会警告我有关真正的错误我有制成。
另一方面:如果存在像Dafny(来自微软)这样的语言,那就是功能性的,我会很乐意尝试这种语言。
编辑:如果没有办法,请回答说明。在这种情况下,我将构建一个过滤掉这些警告的命令行工具。 (但这可能会抹掉所有格式......)
答案 0 :(得分:6)
你很有可能知道,你可以这样写:
let name = function
| [a; b; ... ] -> { ... }
| _ -> failwith "not possible"
但您可以(如果您坚持)通过在[@warning "-8"]
和函数名称之间写let
来禁用警告。
$ cat warn.ml
let f [a; b] = a + b
$ ocamlc -c warn.ml
File "warn.ml", line 1, characters 6-20:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
(_::_::_::_|_::[]|[])
$ cat nowarn.ml
let [@warning "-8"] f [a; b] = a + b
$ ocamlc -c nowarn.ml
$
<强>更新强>
我找到了一种方法来重新启动功能正文的警告,虽然看起来很笨重:
$ cat semiwarn.ml
let [@warning "-8"] f [a; b] =
begin [@warning "+8"]
let a' =
match a with
| 0 -> 14
| 1 -> 15
in
a' + b
end
$ ocamlc -c semiwarn.ml
File "semiwarn.ml", line 4, characters 4-52:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
2
如您所见,函数正文中存在匹配警告,但函数参数没有警告。
总的来说,如果你希望人们阅读代码,这似乎有点混乱,不是一个好的选择。
答案 1 :(得分:1)
另一方面:如果存在像Dafny(来自微软)这样的语言,那就是功能性的,我很乐意尝试那种语言。
OCaml的类型系统足以表达这种类型的不变量:您可以使用GADT定义长度索引列表。
您必须首先介绍类型级自然数:
type zero = Zero
type 'a succ = Succ
他们并不完全是类型级自然数,因为您可以编写非感性表达式,例如int list succ
,但它们足够接近我们的目的:我们类型长度的数据构造函数 - 索引列表将强制该长度仅由succ
和最后的zero
组成。我还必须为这些类型中的每一个提供reasons outside the scope of this answer的构造函数。
然后,您可以定义('a, 'n) vector
类似'a list
的{{1}}长度'n
,如下所示:
type ('a, _) vector =
| [] : ('a, zero) vector
| (::) : 'a * ('a, 'n) vector -> ('a, 'n succ) vector
通过使用[]
和(::)
作为构造函数,您可以在定义list
时重用param
语法。我希望有可能写(int, 4) vector
,但我找不到办法。
let param : (int, zero succ succ succ succ) vector = [3;1;0;4]
或者,您可以让OCaml推断出param_
中的参数。您没有明确说明不变量,但会在每个使用点进行检查。
let param_ : (int, _) vector = [3;1;0;4]
let () = match param_ with
(* [x;y;z] -> print "Argh!\n" (* This doesn't typecheck *)*)
[x;y;z;t] -> print_string "Yeah!\n"