Skip to content

Instantly share code, notes, and snippets.

@jchavarri
Created January 7, 2019 00:16
Show Gist options
  • Save jchavarri/0455be2984480313bd1800b14b01251c to your computer and use it in GitHub Desktop.
Save jchavarri/0455be2984480313bd1800b14b01251c to your computer and use it in GitHub Desktop.
SlotsCreateContainsVariables.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;
module type Component = {
type slots;
type createElement;
let createElement: createElement;
};
let createComponent =
(
type c,
type s,
create:
(
(
Slots.t(s, _) => element,
~children: list(element),
Slots.t(s, _)
) =>
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);
slots => {
let childElement = userRender(slots);
childElement;
};
});
});
/* Fails with: "Error: The type of this packed module contains variables" */
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