Reputation: 3702
OCaml's option type is really useful in cases where you have functions that might not return anything. But when I use this in many places, I find it cumbersome to handle the Some
case and the None
case all the time in a match ... with
.
For example,
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
Are there any other ways to deconstruct the option type in a concise manner?
Upvotes: 4
Views: 1514
Reputation: 66803
For simple cases, you can match several things at once:
match t, it with
| Some t, _ -> (v, t)
| None, Some it -> (v, it)
| None, None -> failwith "Cannot infer local vars"
This is something I do all the time. I'm told the compiler is good with this construct (it doesn't actually generate an extra pair).
Upvotes: 10
Reputation: 1895
Just
in Haskell is Some
in OCaml and Nothing
in Haskell is None
in OCaml. http://en.wikipedia.org/wiki/Option_type#The_option_monaddefault : 'a -> 'a option -> 'a
, map_option : ('a -> 'b) -> 'a option -> 'b option
, or_else
as in another answer, map_some : ('a -> 'b option) -> 'a list -> 'b list
, concat_some : 'a option list -> 'a list
etc. My names might not be standard.unsome : 'a option -> 'a
, let unsome = function Some a -> a | None -> raise Not_found
. Actually, this is useful if you have higher-order functions to deal with the pervasive Not_found
exception.Upvotes: 0
Reputation: 5069
Depending on what you want to do, there are a variety of things you could write to help deal with these. For this pattern, I'd suggest writing something like the following:
let or_else opt1 opt2 = match opt1 with
| Some _ -> opt1
| None -> opt2
And then restructuring your code as:
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
If you've got more than this number of options, then you can fold or_else
over them in a list:
let a = [None; None; Some 1; Some 2;];;
List.fold a ~init:None ~f:or_else;;
Upvotes: 1