One thing is not obvious to me. Is createFoo function pure? I suppose it is. But we can not replace readFromDOM with value, so it's not referential transparent I suppose. Should we use IO?
export const createFoo = (
value: JSON,
readFromDOM: (selector: string) => Option<Element>,
): Foo => {
// We use value for reading from DOM.
};
readFromDOM: (selector: string) => Option<Element> should be readFromDOM: (selector: string) => IO<Option<Element>>, so createFoo should return IO<Foo>.
OK, this talk explains it. https://www.youtube.com/watch?v=cxs7oLGrxQ4
A function is not and can not be pure when the injected function is impure.
Most helpful comment
readFromDOM: (selector: string) => Option<Element>should bereadFromDOM: (selector: string) => IO<Option<Element>>, socreateFooshould returnIO<Foo>.