Skip to content

Instantly share code, notes, and snippets.

@vogler
Last active October 27, 2017 09:43
Show Gist options
  • Save vogler/52fa18234e45157c8d554d85c9da6956 to your computer and use it in GitHub Desktop.
Save vogler/52fa18234e45157c8d554d85c9da6956 to your computer and use it in GitHub Desktop.
ppx_reflect
(** identifiers *)
(* name of identifier as string *)
let%id foo = declare Int
let foo = declare Int "foo"
(* name of module as string *)
module%id Foo = struct end
module Foo = struct let name = "Foo" end
module%id Foo (Bar : S) = struct end
module Foo (Bar : S) = struct let name = "Foo (Bar)" end (* ? *)
(** types *)
(* type of an expression. TODO what type to use for type? *)
[%typ: expr]
type_of expr
(* module signatures *)
module Foo [@implements S] = ..
(* makes sure that Foo fulfills S without limiting visibility to the signature *)
module Foo = ..
module Foo_sealed : S = Foo (* pollutes namespace *)
let _ = let module X : S = Foo in () (* better *)
(* check multiple signatures without having to define a signature that includes them (saves defining up to 2^n signatures). *)
module Foo [@implements S1, S2] = ..
(* yields *)
module Foo = ..
let _ = let module X : sig include S1 include S2 end = Foo in ()
(* Inject code in every module that implements a given signature S.
These could be arbitrarily many with first class modules, but static functor applications would be fine. *)
module type S = sig
val f : int -> int
end
module Test (X : S) = struct
let f x =
assert (f 0 = 0);
X.f x
end
module Impl1 : S = struct
let f x = 0
include Test (struct let f = f end)
end
(* could be generated with *)
module type S [@inject Test] = sig ...
(** example: DSL *)
type typ = Byte | Int
let declare typ name =
print_endline ((show_typ typ)^" "^name^";")
typ, name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment