I have a GADT type for representing an AST and would like to have a function that gives me a list of a nodes children wrapped in polyvariant
let take_next : type a. a t -> [`Expr of expr t | `Stmt of stmt t | `Decl of decl t] list =
let module Opt = struct
open Option
let expr = map (fun x -> `Expr x)
let stmt = map (fun x -> `Stmt x)
let decl = map (fun x -> `Decl x)
end in
function
| CompoundStmt lst -> lst |> List.map (fun stmt -> `Stmt stmt)
| DeclStmt decl -> [`Decl decl]
| CastExpr {expr; _}
| UpdateExpr {expr; _}
| UnaryExpr {expr; _}
| FieldExpr {expr; _}
| RetStmt expr
| ExprStmt expr -> [`Expr expr]
| IfStmt {cond; if_true; if_false} -> cons_opts' [Some (`Expr cond); Some (`Stmt if_true); Opt.stmt if_false]
| ForStmt {init; cond; update; body} -> cons_opts' [Opt.stmt init; Opt.expr cond; Opt.expr update; Some (`Stmt body)]
| SwitchStmt {cond; body}
| WhileStmt {cond; body}
| DoStmt {cond; body} -> [`Expr cond; `Stmt body]
| LabeledStmt {body; _} -> [`Stmt body]
| CaseStmt {body; _} -> [`Stmt body] (* Ignore cond for now *)
| FuncDecl {args; body; _} -> (`Stmt body)::(args |> List.map (fun arg -> `Decl arg))
| VarDecl {init; _} -> cons_opts' [Opt.expr init]
| IndexExpr {expr; index} -> [`Expr expr; `Expr index]
| CommaExpr (lhs, rhs)
| BinExpr {lhs; rhs; _} -> [`Expr lhs; `Expr rhs]
| CallExpr {args; _} -> args |> List.map (fun arg -> `Expr arg)
| CondExpr {cond; if_true; if_false} -> [`Expr cond; `Expr if_true; `Expr if_false]
| _ -> []
Unfortunately I get this message which means just about nothing to me. And for that matter I don’t think what I’m asking for is unreasonable, just a function from GADT type to list of fixed types.
Error: This definition has type
'a t -> [ `Decl of decl t | `Expr of expr t | `Stmt of stmt t ] list
which is less general than
'a0.
'a0 t ->
[ `Decl of decl t | `Expr of expr t | `Stmt of stmt t ] list
I’ve found these posts when searching for my issue but again don’t see how they’d be relevant as no permutation of proposed type annotations would make the compiler shut up which leads me to believe that it’s just not possible for some hand wavy reason