是否有其他方法可以在OCaml中解构选项类型?

时间:2013-02-20 14:13:43

标签: ocaml ml code-readability

OCaml的选项类型在您的函数可能不返回任何内容的情况下非常有用。但是当我在很多地方使用它时,我发现在Some中始终处理None案例和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

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

3 个答案:

答案 0 :(得分:9)

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

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

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

答案 1 :(得分: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;;

答案 2 :(得分:0)

  • 选项monad(又名monad)。请注意,Haskell中的Just在OCaml中为Some,而在Haskell中的Nothing在OCaml中为Nonehttp://en.wikipedia.org/wiki/Option_type#The_option_monad
  • 高阶函数:default : 'a -> 'a option -> 'amap_option : ('a -> 'b) -> 'a option -> 'b optionor_else,如另一个答案,map_some : ('a -> 'b option) -> 'a list -> 'b listconcat_some : 'a option list -> 'a list等。我的名字可能不标准。
  • 如果您遇到麻烦,unsome : 'a option -> 'alet unsome = function Some a -> a | None -> raise Not_found。实际上,如果您具有处理普遍Not_found异常的高阶函数,这将非常有用。