Skip to content

Instantly share code, notes, and snippets.

@aitoroses
Created June 23, 2020 08:46
Show Gist options
  • Save aitoroses/29500da7687b03c081a0f6c6fa91de9a to your computer and use it in GitHub Desktop.
Save aitoroses/29500da7687b03c081a0f6c6fa91de9a to your computer and use it in GitHub Desktop.
Using GADT's to parametrize functions
module Arg = {
type arg(_) =
| Arg(argument('a)): arg('a)
and argument('a) =
| Scalar({
name: option(string),
description: option(string),
validator: 'a => bool,
})
and arglist(_, _) =
| []: arglist('a, 'a)
| ::(arg('a), arglist('b, 'c)): arglist('b, 'a => 'c);
let scalar = (~name=None, ~description=None, ~validator=_ => true, ()) =>
Scalar({name, description, validator});
let int = (~name=None, ~description=None, ~validator=(a: int) => true, ()) => {
Arg(scalar(~name, ~description, ~validator, ()));
};
let string =
(~name=None, ~description=None, ~validator=(a: string) => true, ()) => {
Arg(scalar(~name, ~description, ~validator, ()));
};
};
module Schema = {
type field(_) =
| Field(fieldDefinition('a, 'args)): field('a)
and fieldDefinition('a, 'args) = {
args: Arg.arglist('a, 'args),
resolve: 'args,
};
let field = (~args, ~resolve) => Field({resolve, args});
};
let schema = {
open! Arg;
let args = [int(), string()];
let field =
Schema.field(~args, ~resolve=(param1, param2) =>
Some(param1->string_of_int ++ param2)
);
field;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment