Skip to content

Instantly share code, notes, and snippets.

@pakoito
Forked from i-am-tom/comonads.js
Created Jul 18, 2018
Embed
What would you like to do?
const Day = ({ get, left, right }) => {
const map = f => Day ({
get: f (extract()),
left, right
})
const extend = f =>
Day ({
get: (left, right) => f (Day ({ get, left, right })),
left: left.extend(f),
right: right.extend(f)
})
const extract = () =>
get(left.extract(),
right.extract())
return ({
get,
left,
right,
map,
extend,
extract
})
}
const Store = ({ state, render }) => {
const map = f => Store ({
state,
render: state =>
f (render (state))
})
const extend = f =>
Store ({
state,
render: state =>
f (Store ({ state, render }))
})
const extract = () =>
render (state)
return ({
state,
render,
map,
extend,
extract
})
}
const Moore = ({ handle, view }) => {
const map = f => Moore({
view: f (view),
handle: update => handle(update).map(f)
})
const extend = f => Moore({
view: f (Moore ({ handle, view })),
handle: update => handle(update).extend(f)
})
const extract = () => view
return ({
handle,
view,
map,
extend,
extract
})
}
const Cofree = ({ head, tail }) => {
const map = f => Cofree({
head: f (head),
tail: tail.map(cofree => cofree.map(f))
})
const extend = f => Cofree({
head: f (Cofree ({ head, tail })),
tail: tail.map(cofree => cofree.extend(f))
})
const extract = () => head
return ({
head,
tail,
map,
extend,
extract
})
}
const Sum = ({ side, left, right }) => {
const map = f => Sum ({
side,
left: left.map(f),
right: right.map(f)
})
const extend = f => Sum ({
side,
left: f (Sum ({ side: false, left, right })),
right: f (Sum ({ side: true, left, right })),
})
const extract = () =>
side
? left.extract()
: right.extract()
return ({
side,
left,
right,
map,
extend,
extract
})
}
const Option = ({ then, or, choice }) => {
const map = f => Option({
then: f(then),
or: or.map(f),
choice
})
const extend = f => Option({
then: f (Option ({ then, or, choice: false })),
or: or.extend(inner => f (
Option ({
then,
or: inner,
choice: false
})
)),
choice
})
const extract = () =>
choice
? then
: or.extract()
return ({
then,
or,
choice,
map,
extend,
extract
})
}
const Identity = x => ({
extend: f => f(Identity(x)),
extract: () => x
})
const Pair = (left, right) => ({
left,
right,
extend: f => Pair(left, Pair(left, right)),
extract: () => right,
})
// Component {
const myApplication = Store({
state: "Tom",
render: name => "Hello, " + name + "!"
})
const updateState = (state, store) =>
store
.extend(x => x)
.render(state)
console.log(
myApplication
.extend(({ state }) =>
state == "Tom" ? "TRADE SECRETS" : state)
.extract()
)
// }
// Router {
const handle = ({ route, data }) => {
switch (route) {
case "about": return Moore({
view: Identity("ABOUT"),
handle
})
case "home": return Moore({
view: Identity("HOME"),
handle
})
}
}
const App = Moore({
view: Identity("???"),
handle
})
console.log(
App
.handle({ route: "about", data: {} })
.extract().extract()
)
// }
// Sitemap {
const Sitemap = Cofree({
head: "habito.com",
tail: [
Cofree({
head: "/about",
tail: []
}),
Cofree({
head: "/refer",
tail: [
Cofree({
head: "/terms",
tail: []
})
]
}),
]
})
const countLinksInNode = node =>
1 + node.tail.map(countLinksInNode)
.reduce((x, y) => x + y, 0)
console.log(Sitemap.extend(countLinksInNode))
// }
// Notifications {
const Notifications = Sum({
side: true,
left: Identity("ALL"),
right: Identity("MENTIONS")
})
const showSide = (side, current) =>
Sum({
side,
left: current.left,
right: current.right
})
console.log(
showSide(false, Notifications)
.extract()
)
// }
// Split plane {
const Split = Day({
get: (left, right) => `
<div>
<div class="left">${ left }</div>
<div class="right">${ right }</div>
</div>
`,
left: Identity("MAGICAL JAVASCRIPT"),
right: Identity("REPL")
})
console.log(Split.extract())
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment