所以我注意到可以用“let”表达式重建任何模式,即使它是一个函数声明。
它在以下情况下非常有用:
let [c; f; x] = map (fun _ -> scanf " %f" id) (1--3) in ...
但是,这会发出警告,因为该模式并不详尽:实际上,它可能会失败。但就我而言,这正是模式不匹配时的预期行为(并且我对输入的断言是错误的):语句应该失败(并且可能会在堆栈上的某个点捕获失败)。
我不喜欢这些警告(而且我不想全局关闭它们!),所以我被迫求助于非常麻烦的(而且并不安全):
let c, f, x = match (map (fun _ -> scanf " %f" id) (1--3)) with
| [c; f; x] -> c, f, x
| _ -> failwith "wrong assertion"
in ...
有没有办法获得第一个替代方案的简洁语法,而没有可怕的警告?或者另一种结构,比完整的匹配语句涉及更少的打字?
注意:我认为能够指定一个函数仅采用给定的 sum 类型替代方案而不在声明站点发出警告也是很好的。调用者需要确保他使用正确的参数,否则他会收到警告......
type ast = Id of string | Var of string * int
let foo (Var(s,n)) = ...
foo (Var("bar", 42)) (* ok *)
foo (Id "bar") (* warning; or even error *)
(这是因为对我来说,像“foo s n”这样的签名并不能清楚地表明 foo 旨在与 Var 构造的 ast 的数据一起使用。)
最佳答案
您可以使用变体类型:
type ast = [`Id of string | `Var of string * int]
let foo (`Var (s, n)) = (s, n)
(* val foo : [< `Var of 'a * 'b ] -> 'a * 'b *)
foo (`Var("bar", 42)) (* : string * int = ("bar", 42) *)
foo (`Id "bar") (* Error: This expression has type [> `Id of string ] *)
关于pattern-matching - 使用 let 重建 OCaml 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23038649/