Last active
January 2, 2019 21:35
-
-
Save cristianoc/0cb8afcfca272f17bb001ffa26983126 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module State: { | |
type t('a); | |
let createSlot: (t('a) => 'b) => 'b; | |
let useHook: ('a, t('a)) => ('a, 'a => unit); | |
} = { | |
type t('a) = ref(option('a)); | |
let createSlot = cont => cont(ref(None)); | |
let useHook = (initial: 'a, slot: t('a)) => { | |
let state = | |
switch (slot^) { | |
| None => initial | |
| Some(state) => state | |
}; | |
let setState = value => { | |
Js.log2("setState", value); | |
slot := Some(value); | |
}; | |
(state, setState); | |
}; | |
}; | |
module Effect: { | |
type t; | |
type callback = unit => unit; | |
let createSlot: unit => t; | |
let useHook: (callback, t) => unit; | |
} = { | |
type t = unit; | |
let createSlot = () => (); | |
type callback = unit => unit; | |
let useHook = (callback: callback, _slot: t) => callback(); | |
}; | |
module Run = { | |
let testState = testFunction => | |
State.createSlot(slot => (slot, ()) |> testFunction); | |
let testEffect = testFunction => (Effect.createSlot(), ()) |> testFunction; | |
let testStateState = testFunction => | |
State.createSlot(slot1 => | |
State.createSlot(slot2 => (slot1, (slot2, ())) |> testFunction) | |
); | |
let testStateEffect = testFunction => | |
State.createSlot(slot1 => { | |
let slot2 = Effect.createSlot(); | |
(slot1, (slot2, ())) |> testFunction; | |
}); | |
let testEffectState = testFunction => | |
State.createSlot(slot2 => { | |
let slot1 = Effect.createSlot(); | |
(slot1, (slot2, ())) |> testFunction; | |
}); | |
let testStateStateState = testFunction => | |
State.createSlot(slot1 => | |
State.createSlot(slot2 => | |
State.createSlot(slot3 => | |
(slot1, (slot2, (slot3, ()))) |> testFunction | |
) | |
) | |
); | |
}; | |
let useSlot = (useHook, slots, continuation) => { | |
let (slot, nextSlots) = slots; | |
continuation(nextSlots, useHook(slot)); | |
}; | |
let useState = (slots, initial) => useSlot(State.useHook(initial), slots); | |
let useEffect = (slots, callback) => | |
useSlot(Effect.useHook(callback), slots); | |
let testIntState = slots => | |
useState( | |
slots, | |
3, | |
(_nextSlots, (count, setCount)) => { | |
setCount(count + 1); | |
(); | |
}, | |
); | |
let runTestIntState = testIntState |> Run.testState; | |
let testStringState = slots => | |
useState( | |
slots, | |
"", | |
(_nextSlots, (count, setCount)) => { | |
setCount(count ++ "x"); | |
(); | |
}, | |
); | |
let runTestStringState = testStringState |> Run.testState; | |
let testStringIntState = slots => | |
useState( | |
slots, | |
"", | |
(nextSlots, (count, setCount)) => { | |
setCount(count ++ "x"); | |
nextSlots |> testIntState; | |
}, | |
); | |
let runTestStringIntState = testStringIntState |> Run.testStateState; | |
/* let testConditionalWrong = (slots, cond) => { | |
cond ? slots |> testIntState : slots |> testStringState; | |
}; */ | |
let testConditionalOK1 = (slots, cond) => { | |
cond ? slots |> testStringState : slots |> testStringIntState; | |
}; | |
/* let testSequenceWrong = (slots) => { | |
slots |> testIntState; | |
slots |> testStringState; | |
}; */ | |
let testSequenceOK = slots => { | |
slots |> testIntState; | |
slots |> testIntState; | |
}; | |
let testEffectSequenceOK = slots => | |
useEffect( | |
slots, | |
() => Js.log("hello"), | |
(nextSlots, ()) => nextSlots |> testSequenceOK, | |
); | |
let runTestEffectSequenceOK = testEffectSequenceOK |> Run.testEffectState; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment