Skip to content

Instantly share code, notes, and snippets.

@EduardoRFS
Created March 16, 2021 18:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EduardoRFS/af775b235d68b3db132d30e35a8f930b to your computer and use it in GitHub Desktop.
Save EduardoRFS/af775b235d68b3db132d30e35a8f930b to your computer and use it in GitHub Desktop.
[@ocaml.ppx.context
{
tool_name: "ppxlib_driver",
include_dirs: [],
load_path: [
"",
"/home/eduardo/.esy/3_________________________________________________________________/i/ocaml-4.10.2000-76cdf1b9/lib/ocaml",
],
open_modules: [],
for_package: None,
debug: false,
use_threads: false,
use_vmthreads: false,
recursive_types: true,
principal: false,
transparent_modules: false,
unboxed_types: false,
unsafe_string: false,
cookies: [],
}
];
module type Show = {
type t;
let show: t => string;
};
[@implicit]
module Show_string = {
type t = string;
let show = x => x;
};
[@implicit]
module Show_int = {
type t = int;
let show = Int.to_string;
};
[@implicit]
module Show_list = (S: Show) => {
type t = list(S.t);
let show = v => "[" ++ String.concat(", ", List.map(S.show, v)) ++ "]";
};
module type HKT_Magic_0 = {
module S: Show;
[@hkt_defined: S.t]
type nonrec a;
[@hkt_defined: string]
type nonrec b;
type eq('a, 'b) =
| Eq: eq('a, 'a);
let eq: eq((a, b), (S.t, string));
};
let show =
(
type a,
type b,
module S: HKT_Magic_0 with type a = a and type b = b,
v: a,
)
: b =>
switch (S.eq) {
| Eq => S.(S.show(v))
};
let map = (v, f) => List.map(f, v);
let five =
show(
[@hkt_applied]
(module
{
module S = Show_int;
type nonrec a = S.t;
type nonrec b = string;
type eq('a, 'b) =
| Eq: eq('a, 'a);
let eq = Eq;
}),
5,
);
let a =
show(
[@hkt_applied]
(module
{
module S = Show_string;
type nonrec a = S.t;
type nonrec b = string;
type eq('a, 'b) =
| Eq: eq('a, 'a);
let eq = Eq;
}),
"a",
);
let one_two_three =
show(
[@hkt_applied]
(module
{
module S = Show_list(Show_int);
type nonrec a = S.t;
type nonrec b = string;
type eq('a, 'b) =
| Eq: eq('a, 'a);
let eq = Eq;
}),
[1, 2, 3],
);
module type Monad = {
type t('a);
let return: 'a => t('a);
let bind: (t('a), 'a => t('b)) => t('b);
};
[@implicit]
module Option = {
include Option;
let return = Option.some;
};
[@implicit]
module List = {
include List;
let return = v => [v];
let bind = (ls, f) => concat_map(f, ls);
};
module type HKT_Magic_1 = {
module M: Monad;
[@hkt_defined]
type nonrec a;
[@hkt_defined]
type nonrec b;
[@hkt_defined: M.t('a)]
type nonrec c;
[@hkt_defined: 'a => M.t('b)]
type nonrec d;
[@hkt_defined: M.t('b)]
type nonrec e;
type eq('a, 'b) =
| Eq: eq('a, 'a);
let eq: eq((c, d, e), (M.t(a), a => M.t(b), M.t(b)));
};
let bind =
(
type a,
type b,
type c,
type d,
type e,
module M:
HKT_Magic_1 with
type a = a and
type b = b and
type c = c and
type d = d and
type e = e,
v: c,
f: d,
)
: e =>
switch (M.eq) {
| Eq => M.(M.bind(v, f))
};
let bind_some_5 = f =>
(
(type a, type b) =>
bind(
[@hkt_applied]
(module
{
module M = Option;
type nonrec a = a;
type nonrec b = b;
type nonrec c = M.t(a);
type nonrec d = a => M.t(b);
type nonrec e = M.t(b);
type eq('a, 'b) =
| Eq: eq('a, 'a);
let eq = Eq;
}),
)
)(
Some(5),
f,
);
let bind_list_3 =
(
(type a, type b) =>
bind(
[@hkt_applied]
(module
{
module M = List;
type nonrec a = a;
type nonrec b = b;
type nonrec c = M.t(a);
type nonrec d = a => M.t(b);
type nonrec e = M.t(b);
type eq('a, 'b) =
| Eq: eq('a, 'a);
let eq = Eq;
}),
)
)(
[1, 2, 3], x =>
[x + 1]
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment