Skip to content

Instantly share code, notes, and snippets.

@buzzdecafe
Last active February 4, 2018 15:54
Show Gist options
  • Save buzzdecafe/5ab68c216bf1a919cdda32917cd4768d to your computer and use it in GitHub Desktop.
Save buzzdecafe/5ab68c216bf1a919cdda32917cd4768d to your computer and use it in GitHub Desktop.
/*
data Store s a = Store (s -> a) s
instance Functor (Store s) where
fmap f (Store g s) = Store (f . g) s
instance Extend (Store s) where
duplicate (Store f s) = Store (Store f) s
instance Comonad (Store s) where
extract (Store f s) = f s
*/
// also see: http://package.elm-lang.org/packages/joneshf/elm-comonad/1.0.0/Store
// compose all the things
const o = f => g => x => f(g(x));
// here :: s
// view :: s -> a
const Store = here => view => ({
map: f => Store(here)(o(f)(view)),
duplicate: () => Store(here)(next => Store(next)(view)),
extract: () => view(here),
move: s => Store(s)(view)
});
// closer to the Elm impl
const Store = (here, view) => ({ here, view });
const o = f => g => x => f(g(x));
const map = f => s => Store(s.here, o(f)(s.view));
const duplicate = s => Store(s.here, next => Store(next, s.view));
const extract = s => s.view(s.here);
const move = s => sa => duplicate(sa).view(s);
// we can derive the `extend` (the inverse of monadic `bind`) from the above:
// extend :: Comonad w => (w a -> b) -> w a -> w b
const extend f = o(map(f))(duplicate);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment