Skip to content

Instantly share code, notes, and snippets.

@jchavarri
Forked from cristianoc/LinearHooksViaTypes.re
Last active December 23, 2018 18:12
Show Gist options
  • Save jchavarri/20dd12fd668c7d100bf6cbe17044da48 to your computer and use it in GitHub Desktop.
Save jchavarri/20dd12fd668c7d100bf6cbe17044da48 to your computer and use it in GitHub Desktop.
module HookTypes = {
type state('a);
type effect;
type t('t);
let addState: (~state: 'state, t('t)) => t(('t, state('state))) =
(~state as _, x) => Obj.magic(x);
let addEffect: t('t) => t(('t, effect)) = Obj.magic;
};
let useState = (state, hooks) => {
let setState = x => ignore(x == state);
(hooks |> HookTypes.addState(~state), state, setState);
};
let useEffect = (_functionWithEffects: unit => unit, hooks) =>
hooks |> HookTypes.addEffect;
let functionComponent = (~message, ~hooks) => {
let (_, name, _setName) = hooks |> useState("Harry");
let (_, surname, _setSurname) = hooks |> useState("Potter");
let stringToRender = message ++ " " ++ name ++ " " ++ surname;
(hooks, stringToRender);
};
let customHookNameSurname = (hooks, ~initialName, ~initialSurname) => {
let (_, name, setName) = hooks |> useState(initialName);
let (_, surname, setSurname) = hooks |> useState(initialSurname);
(hooks, name, setName, surname, setSurname);
};
let functionComponent2 = (~message, ~hooks) => {
let (_, name, _setName, surname, _setSurname) =
hooks
|> customHookNameSurname(~initialName="Harry", ~initialSurname="Potter");
let stringToRender = message ++ " " ++ name ++ " " ++ surname;
(hooks, stringToRender);
};
let checkThatTheTwoFunctionsHaveTheSameType =
ignore(functionComponent == functionComponent2);
let effectBeforeState = (~hooks) => {
let hooks = hooks |> useEffect(() => print_endline("About so use State"));
let (hooks, _name, _setName) = hooks |> useState("Harry");
hooks;
};
let effectAfterState = (~hooks) => {
let (hooks, _name, _setName) = hooks |> useState("Harry");
let hooks = hooks |> useEffect(() => print_endline("Just Used State"));
hooks;
};
/*
let checkThatTheOrderMatters =
ignore(effectBeforeState == effectAfterState);
*/
/* let thisDoesNotTypeCheck = (~message, ~hooks) => {
let (hooks, _name, _setName) =
Random.bool() ? useState("Harry", hooks) : (hooks, "", _ => ());
hooks;
}; */
let theTypeCheckerIsSmart = (~message, ~hooks) => {
let (_, name, _setName, surname, _setSurname) =
Random.bool() ?
{
/* One call to `useState` */
let (_, name, setName) = hooks |> useState("Harry");
(hooks, name, setName, "joe", (_) => ());
} :
{
/* Two calls to `useState` */
let (_, name, setName, surname, setSurname) =
hooks
|> customHookNameSurname(
~initialName="Harry",
~initialSurname="Potter",
);
(hooks, name, setName, surname, setSurname);
};
let stringToRender = message ++ " " ++ name ++ " " ++ surname;
(hooks, stringToRender);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment