Skip to content

Instantly share code, notes, and snippets.

@jchavarri
Created January 6, 2019 11:43
Show Gist options
  • Save jchavarri/ca0ec4f791c399fa3fba6bf8587b8755 to your computer and use it in GitHub Desktop.
Save jchavarri/ca0ec4f791c399fa3fba6bf8587b8755 to your computer and use it in GitHub Desktop.
SlotsCreateComponentWorking.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;
module type Component = {
type element;
type slots;
type createElement;
let createElement: createElement;
let createSlots: unit => Slots.t(slots, _);
};
let createComponent =
(type c, type e, type s, create: (e => e, Slots.t(s, _)) => c)
: (module Component with
type createElement = c and type element = e and type slots = s) =>
(module
{
type element = e;
type slots = s;
type createElement = c;
let createSlots = () => Slots.create();
let createElement = create(x => x, createSlots());
});
module MyComponent = (
val createComponent((render, slots, ~one, ~two) =>
render(
{
let (state, slots) = useState(3, slots);
let (stateStr, _slots) = useState("3", slots);
primitive(one + two + state + int_of_string(stateStr));
},
)
)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment