Skip to content

Instantly share code, notes, and snippets.

@jchavarri
Created January 7, 2019 13:39
Show Gist options
  • Save jchavarri/79483111217d873053db0b754313e4aa to your computer and use it in GitHub Desktop.
Save jchavarri/79483111217d873053db0b754313e4aa to your computer and use it in GitHub Desktop.
SlotsPassedToUserRender.re
module type SlotsType = {
type t('slot, 'nextSlots);
let create: unit => t('slot, 'nextSlots);
let use:
(~default: 'slot, t('slot, t('slot2, 'nextSlots))) =>
('slot, t('slot2, 'nextSlots));
};
module Slots: SlotsType = {
type t('slot, 'nextSlots) = ref(option(('slot, 'nextSlots)));
let create = () => ref(None);
let use = (~default, slots: t(_)) =>
switch (slots^) {
| None =>
let slot = default;
let nextSlots = create();
slots := Some((slot, nextSlots));
(slot, nextSlots);
| Some((slot, nextSlots)) => (slot, nextSlots)
};
};
let useState = (initial, slots) => slots |> Slots.use(~default=initial);
let primitive: 'a => 'a = x => x;
type element = int;
type opaqueSlots =
| OpaqueSlots(Slots.t('slot, 'nextSlots)): opaqueSlots;
module type Component = {
type slots;
type createElement;
let createElement: createElement;
};
let createComponent =
(
type c,
type s,
create:
(
(Slots.t(s, _) => element, ~children: list(element), opaqueSlots) =>
element
) =>
c,
)
: (module Component with type createElement = c and type slots = s) =>
(module
{
type slots = s;
type createElement = c;
let createElement =
create((userRender, ~children) => {
ignore(children);
(OpaqueSlots(slots)) => {
/* Error: This expression has type
($OpaqueSlots_'slot, $OpaqueSlots_'nextSlots) Slots.t
but an expression was expected of type (slots, 'a) Slots.t
Type $OpaqueSlots_'slot is not compatible with type slots */
let childElement = userRender(slots);
childElement;
};
});
});
module MyComponent = (
val createComponent((render, ~one, ~two, ~children, ()) =>
render(
slots => {
let (state, slots) = useState(3, slots);
let (stateStr, _slots) = useState("3", slots);
primitive(one + two + state + int_of_string(stateStr));
},
~children,
)
)
);
let comp = <MyComponent one=1 two=2 />;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment