-
Notifications
You must be signed in to change notification settings - Fork 465
/
Copy pathvariant_coercion.ml
38 lines (31 loc) · 1.46 KB
/
variant_coercion.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
type variant_representation = String | Int | Float | Other
let find_as_attribute_payload (attributes : Parsetree.attribute list) =
attributes
|> List.find_map (fun (({txt = name}, payload) : Parsetree.attribute) ->
match (name, payload) with
| ( "as",
PStr
[
{
pstr_desc =
Pstr_eval ({pexp_desc = Pexp_constant constant}, _);
};
] ) ->
Some constant
| _ -> None)
let constructors_representations
(constructors : Types.constructor_declaration list) =
constructors
|> List.map (fun (c : Types.constructor_declaration) ->
match (c.cd_args, c.cd_attributes |> find_as_attribute_payload) with
| Cstr_tuple [], (Some (Pconst_string _) | None) -> String
| Cstr_tuple [], Some (Pconst_integer _) -> Int
| Cstr_tuple [], Some (Pconst_float _) -> Float
| _ -> Other)
(* TODO: Improve error messages? Say why we can't coerce. *)
let can_coerce_to_string (constructors : Types.constructor_declaration list) =
constructors |> constructors_representations |> List.for_all (( = ) String)
let can_coerce_to_int (constructors : Types.constructor_declaration list) =
constructors |> constructors_representations |> List.for_all (( = ) Int)
let can_coerce_to_float (constructors : Types.constructor_declaration list) =
constructors |> constructors_representations |> List.for_all (( = ) Float)