Skip to content

Commit 04236a4

Browse files
committed
a alacarte data type counter example
1 parent 88475a3 commit 04236a4

File tree

4 files changed

+3286
-0
lines changed

4 files changed

+3286
-0
lines changed

examples/alacarte/package.json

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"name": "alacarte-example",
3+
"version": "0.0.1",
4+
"description": "",
5+
"browserify": {
6+
"transform": [
7+
[
8+
"babelify",
9+
{
10+
"extensions": [
11+
".es6",
12+
".jsx",
13+
".js"
14+
]
15+
}
16+
]
17+
]
18+
},
19+
"scripts": {
20+
"build": "NODE_ENV=production browserify src/app.jsx --extension=.jsx --extension=.es6 > public/app.js",
21+
"start": "ecstatic -p 8000 public",
22+
"watch": "watchify -d src/app.jsx --extension=.jsx --extension=.es6 -o public/app.js -dv"
23+
},
24+
"jest": {
25+
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
26+
"testFileExtensions": [
27+
"es6",
28+
"js",
29+
"jsx"
30+
],
31+
"moduleFileExtensions": [
32+
"js",
33+
"json",
34+
"es6",
35+
"jsx"
36+
]
37+
},
38+
"dependencies": {
39+
"alacarte.js": "^0.0.1",
40+
"most": "^1.2.2",
41+
"react": "^15.4.2",
42+
"react-dom": "^15.4.2",
43+
"react-most": "^0.7.1"
44+
},
45+
"devDependencies": {
46+
"babel": "^6.1.18",
47+
"babel-jest": "^6.0.0",
48+
"babel-plugin-lodash": "^2.0.1",
49+
"babel-plugin-transform-react-jsx": "^6.1.18",
50+
"babel-preset-es2015": "^6.1.18",
51+
"babelify": "^7.2.0",
52+
"browserify": "^12.0.1",
53+
"ecstatic": "^1.3.1",
54+
"jest-cli": "^0.7.0",
55+
"watchify": "^3.6.1"
56+
},
57+
"author": "Jichao Ouyang",
58+
"license": "ISC",
59+
"babel": {
60+
"presets": [
61+
"es2015"
62+
],
63+
"plugins": [
64+
"transform-react-jsx"
65+
]
66+
}
67+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>counter</title>
7+
</head>
8+
<body>
9+
<h1>counter</h1>
10+
<div id="app"></div>
11+
<footer class="info">
12+
<p>Created by <a href="https://github.com/jcouyang">Jichao Ouyang</a></p>
13+
<p>a <a href="http://github.com/jcouyang/react-most">React Most</a> Example</p>
14+
</footer>
15+
<script src="app.js"></script>
16+
</body>
17+
</html>

examples/alacarte/src/app.jsx

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import React from 'react';
2+
import { render } from 'react-dom';
3+
import Most, { connect } from 'react-most'
4+
import {
5+
injectorFrom,
6+
interpreterFrom,
7+
interpretExpr,
8+
Functor,
9+
interpreterFor,
10+
inject,
11+
} from 'alacarte.js'
12+
13+
const compose = f => g => x=> f(g(x))
14+
function Add(value0) {
15+
this.value0 = value0
16+
}
17+
18+
function Lit(value0) {
19+
this.value0 = value0
20+
}
21+
function Over(value0, value1) {
22+
this.value0 = value0
23+
this.value1 = value1
24+
}
25+
26+
const functorLit = new Functor(f => v => new Lit(v.value0))
27+
const functorAdd = new Functor(f => v => new Add(f(v.value0)))
28+
const functorOver = new Functor(f => v => new Over(f(v.value0), f(v.value1)))
29+
30+
function injectLit(injector) {
31+
return n => inject(injector(functorLit))(new Lit(n))
32+
}
33+
34+
function injectAdd(injector) {
35+
return (a, b) => inject(injector(functorAdd))(new Add(a, b))
36+
}
37+
38+
function injectOver(injector) {
39+
return (a, b) => inject(injector(functorOver))(new Over(a, b))
40+
}
41+
42+
function injectState(injector) {
43+
return n => inject(injector(functorState))(new State(n))
44+
}
45+
46+
const evalAdd = interpreterFor(functorAdd, function (v) {
47+
return x => x + v.value0
48+
});
49+
50+
const evalLit = interpreterFor(functorLit, function (v) {
51+
return v.value0
52+
});
53+
54+
const evalOver = interpreterFor(functorOver, function (v) {
55+
let newstate = {}
56+
return state => (newstate[v.value0] = v.value1(state[v.value0]), newstate)
57+
});
58+
59+
let interpreter = interpreterFrom([evalLit, evalAdd, evalOver])
60+
let injector = injectorFrom([functorLit, functorAdd, functorOver])
61+
62+
let add = injectAdd(injector)
63+
let lit = injectLit(injector)
64+
let over = injectOver(injector)
65+
66+
const printAdd = interpreterFor(functorAdd, function (v) {
67+
return `(_ + ${v.value0})`
68+
});
69+
70+
const printLit = interpreterFor(functorLit, function (v) {
71+
return v.value0.toString()
72+
});
73+
74+
const printOver = interpreterFor(functorOver, function (v) {
75+
return `over ${v.value0} do ${v.value1}`
76+
});
77+
78+
const printer = interpreterFrom([printLit, printAdd, printOver])
79+
const CounterView = props => (
80+
<div>
81+
<button onClick={props.actions.dec}>-</button>
82+
<span>{props.count}</span>
83+
<button onClick={props.actions.inc}>+</button>
84+
</div>
85+
)
86+
87+
CounterView.defaultProps = { count: 0 };
88+
89+
const counterable = connect((intent$) => {
90+
return {
91+
sink$: intent$.tap(compose(console.log)(interpretExpr(printer)))
92+
.map(interpretExpr(interpreter)),
93+
inc: () => over(lit('count'), add(lit(1))),
94+
dec: () => over(lit('count'), add(lit(-1))),
95+
}
96+
})
97+
98+
const Counter = counterable(CounterView)
99+
100+
render(
101+
<Most>
102+
<Counter />
103+
</Most>
104+
, document.getElementById('app'));

0 commit comments

Comments
 (0)