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
有没有其他方法可以简洁地解构选项类型?
答案 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)
Just
在OCaml中为Some
,而在Haskell中的Nothing
在OCaml中为None
。 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
异常的高阶函数,这将非常有用。