Ocaml模式匹配用户定义类型

时间:2018-03-10 23:10:17

标签: types functional-programming ocaml

我正在尝试编写一个函数,该函数可以根据对函数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,我只想在尝试实现这些功能之前尝试编译它。

1 个答案:

答案 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的快速入门教程。一旦你有一些有用的例子,很多这个问题就会很快得到解决。