Created
July 18, 2018 22:32
-
-
Save i-am-tom/f940124e3ed18b2245340c053a3b8b65 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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