【发布时间】:2014-05-27 03:31:58
【问题描述】:
所以我注意到可以用“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-constructed ast 的数据一起使用。)
【问题讨论】:
-
你可以定义
let foo (s, n) = ...,如果可能的话,由调用者从ast获取(s, n)。 -
是的,但这并不能解决问题。例如,如果另一个替代(甚至类型)具有相同的签名怎么办?
-
您可能希望有选择地关闭警告,而不是任何类型的类型级别保证。最好的办法是编写一个语法扩展,将
let派生形式转换为与failwith分支匹配的模式。 -
谢谢,这听起来更像是我想要实现的目标。
标签: pattern-matching ocaml let