我正在尝试编写一个函数,该函数可以根据对函数baz
的调用结果返回int或字符串。
type 'a foo = OK of 'a | Error of string
let bar (e) : int foo =
match baz e with
| OK (_) -> 1
| Error s -> s
但是,我在编译时收到此错误消息:
Error: This expression has type int but an expression was expected of type
int foo
Command exited with code 2.
我到底错在了什么?
编辑:这是我正在处理的实际代码片段:
type 'a error = | OK of 'a | Error of string
type typing_judgement = subst*expr*texpr
let rec infer' (e:expr) (n:int): (int*typing_judgement) error =
match e with
| _ -> failwith "infer': undefined"
let infer_type (AProg e) =
match infer' e 0 with
| OK (_, tj) -> string_of_typing_judgement tj
| Error s -> "Error! "^ s
这里的最终目标是一个类型推理引擎,因此我可以告诉infer_type将给出一个表达式,它将被传递给推断'(我将不得不实现)。我之前从未使用过Ocaml,我只想在尝试实现这些功能之前尝试编译它。
答案 0 :(得分:1)
从您的初始代码看起来,函数似乎是:
let bar e =
(一般情况下,让OCaml推断e的类型)那就是说,当你得到Ok或Error的结果时,这就是你正在寻找的变种(正如glennsl所说)。此时,您可以报告错误或返回一些结果。例如:
let bar e =
match baz e with
| Ok _ -> ()
| Error s ->
let () = prerr_endline ("Error: " ^ s) in
exit 1
Ok示例在我的示例中返回void,因为您的代码似乎并不关心Ok的内容,但您可以简单地返回:
| Ok result -> result
同样,OCaml将推断所有类型,因此不需要像在C / C ++中那样明确。
关于实际代码:failwith将抛出异常。除了"推断"功能清理," infer_type"可能看起来像这样:
let infer_type expr =
try string_of_typing_judgment @@ infer expr
with Failure msg ->
let () = prerr_endline ("Infer failed with: " ^ msg) in
exit 1
@@只是一个方便的操作符,可以避免使用括号。它的含义相同:
string_of_typing_judgment (infer expr)
但是,使用failwith时的整体范例是异常处理。如果您预料到异常,请使用"尝试/使用"语法。
最后,我建议您在开始项目之前通过几个关于OCaml的快速入门教程。一旦你有一些有用的例子,很多这个问题就会很快得到解决。