4

OCaml 的选项类型在您的函数可能不返回任何内容的情况下非常有用。但是当我在很多地方使用这个的时候,我发现SomeNone一个match ... with.

例如,

let env2 = List.map (fun ((it,ie),v,t) ->
  match t with
  | Some t -> (v,t)
  | None   ->
    begin
      match it with
      | Some it -> (v,it)
      | None    -> failwith "Cannot infer local vars"
    end) ls_res in

还有其他方法可以简洁地解构选项类型吗?

4

3 回答 3

10

对于简单的情况,您可以一次匹配多个内容:

match t, it with
| Some t, _ -> (v, t)
| None, Some it -> (v, it)
| None, None -> failwith "Cannot infer local vars"

这是我一直在做的事情。我被告知编译器对这个结构很好(它实际上并没有生成额外的对)。

于 2013-02-20T14:49:59.533 回答
1

根据你想做的事情,你可以写很多东西来帮助处理这些问题。对于这种模式,我建议编写如下内容:

let or_else opt1 opt2 = match opt1 with 
  | Some _ -> opt1
  | None -> opt2

然后将您的代码重组为:

let env2 = List.map (fun ((it,ie),v,t) ->
  match (or_else opt1 opt2) with
  | Some t -> (v,t)
  | None   -> failwith "Cannot infer local vars") ls_res in

如果您有超过这个数量的选项,那么您可以or_else将它们折叠在一个列表中:

let a = [None; None; Some 1; Some 2;];;
List.fold a ~init:None ~f:or_else;;
于 2013-02-20T14:31:49.147 回答
0
  • 选项单子(又名。也许单子)。请注意,Just在 Haskell 中是Some在 OCaml 中,Nothing在 Haskell 中是None在 OCaml 中。http://en.wikipedia.org/wiki/Option_type#The_option_monad
  • 高阶函数:default : 'a -> 'a option -> 'a, map_option : ('a -> 'b) -> 'a option -> 'b option,or_else在另一个答案中map_some : ('a -> 'b option) -> 'a list -> 'b list,concat_some : 'a option list -> 'a list等。我的名字可能不是标准的。
  • 如果你遇到麻烦unsome : 'a option -> 'a,,,let unsome = function Some a -> a | None -> raise Not_found。实际上,如果您有高阶函数来处理普遍的Not_found异常,这很有用。
于 2013-02-20T21:48:27.627 回答