Skip to content

Commit bf2db7c

Browse files
committed
adding mult expr
1 parent a0467dc commit bf2db7c

File tree

3 files changed

+139
-143
lines changed

3 files changed

+139
-143
lines changed

examples/alacarte/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
]
3737
},
3838
"dependencies": {
39-
"alacarte.js": "^0.0.1",
39+
"alacarte.js": "0.0.6",
4040
"most": "^1.2.2",
4141
"react": "^15.4.2",
4242
"react-dom": "^15.4.2",

examples/alacarte/src/app.jsx

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
} from 'alacarte.js'
1313

1414
const compose = f => g => x=> f(g(x))
15+
16+
// Data Types of Exprs
1517
function Add(value0) {
1618
this.value0 = value0
1719
}
@@ -24,10 +26,12 @@ function Over(value0, value1) {
2426
this.value1 = value1
2527
}
2628

29+
// Their Functor Instance
2730
const functorLit = new Functor(f => v => new Lit(v.value0))
2831
const functorAdd = new Functor(f => v => new Add(f(v.value0)))
2932
const functorOver = new Functor(f => v => new Over(f(v.value0), f(v.value1)))
3033

34+
// Injectors
3135
function injectLit(injector) {
3236
return n => inject(injector(functorLit))(new Lit(n))
3337
}
@@ -40,30 +44,32 @@ function injectOver(injector) {
4044
return (a, b) => inject(injector(functorOver))(new Over(a, b))
4145
}
4246

43-
function injectState(injector) {
44-
return n => inject(injector(functorState))(new State(n))
45-
}
46-
47+
// Instances of Interpreters
4748
const evalAdd = interpreterFor(functorAdd, function (v) {
48-
return x => x + v.value0
49+
return x => x + v.value0(x)
4950
});
5051

5152
const evalLit = interpreterFor(functorLit, function (v) {
52-
return v.value0
53+
return ()=> v.value0
5354
});
5455

5556
const evalOver = interpreterFor(functorOver, function (v) {
5657
let newstate = {}
57-
return state => (newstate[v.value0] = v.value1(state[v.value0]), newstate)
58+
let value = v.value0()
59+
return state => (newstate[value] = v.value1(state[value]), newstate)
5860
});
5961

62+
// Compose a Interpreter which can interpret Lit, Add, Over
6063
let interpreter = interpreterFrom([evalLit, evalAdd, evalOver])
64+
// Injector that can inject Lit, Add, Over
6165
let injector = injectorFrom([functorLit, functorAdd, functorOver])
6266

67+
// Expressions
6368
let add = injectAdd(injector)
6469
let lit = injectLit(injector)
6570
let over = injectOver(injector)
6671

72+
// You can define any Interpreters you want, instead of eval value, this interpreter print the expressions
6773
const printAdd = interpreterFor(functorAdd, function (v) {
6874
return `(_ + ${v.value0})`
6975
});
@@ -77,6 +83,7 @@ const printOver = interpreterFor(functorOver, function (v) {
7783
});
7884

7985
const printer = interpreterFrom([printLit, printAdd, printOver])
86+
8087
const CounterView = props => (
8188
<div>
8289
<button onClick={props.actions.dec}>-</button>
@@ -85,21 +92,54 @@ const CounterView = props => (
8592
</div>
8693
)
8794

88-
CounterView.defaultProps = { count: 0 };
95+
CounterView.defaultProps = { count: 1 };
8996

9097
const counterable = connect((intent$) => {
9198
return {
92-
sink$: intent$.filter(supTypeSameAs(injector)).tap(compose(console.log)(interpretExpr(printer)))
93-
.map(interpretExpr(interpreter)),
94-
inc: () => over(lit('count'), add(lit(1))),
95-
dec: () => injectOver(injectorFrom([functorLit, functorOver]))(lit('count'), add(lit(-1)))
99+
sink$: intent$.filter(supTypeSameAs(injector)) // <-- filter only expressions compose with type Lit :+: Add :+: Over
100+
.tap(compose(console.log)(interpretExpr(printer))) // interpret with printer
101+
.map(interpretExpr(interpreter)), // interpret with interpreter(eval value)
102+
inc: () => over(lit('count'), add(add(lit(1)))), // you can compose expressions to achieve your bussiness
103+
dec: () => injectOver(injectorFrom([functorLit, functorOver]))(lit('count'), add(lit(-1))) // a expr with different type like Lit :+: Over will be filtered out(do nothing here)
96104
}
97105
})
98106

107+
const multable = connect((intent$) => {
108+
function Mult(value0) {
109+
this.value0 = value0
110+
}
111+
const functorMult = new Functor(f => v => new Mult(f(v.value0)))
112+
function injectMult(injector) {
113+
return (a, b) => inject(injector(functorMult))(new Mult(a, b))
114+
}
115+
const evalMult = interpreterFor(functorMult, function (v) {
116+
return x => x * v.value0(x)
117+
});
118+
let injector = injectorFrom([functorLit, functorAdd, functorOver, functorMult])
119+
let add = injectAdd(injector)
120+
let lit = injectLit(injector)
121+
let mult = injectMult(injector)
122+
let over = injectOver(injector)
123+
let printMult = interpreterFor(functorMult, function (v) {
124+
return `(_ * ${v.value0})`
125+
});
126+
let interpreter = interpreterFrom([evalLit, evalAdd, evalOver, evalMult])
127+
const printer = interpreterFrom([printLit, printAdd, printOver, printMult])
128+
return {
129+
sink$: intent$.filter(supTypeSameAs(injector))
130+
.tap(compose(console.log)(interpretExpr(printer)))
131+
.map(interpretExpr(interpreter)),
132+
inc: () => over(lit('count'), mult(add(lit(1)))),
133+
}
134+
})
99135
const Counter = counterable(CounterView)
100-
136+
const Counter2 = multable(CounterView)
101137
render(
102-
<Most>
138+
<Most>
139+
<div>
103140
<Counter />
141+
<Counter2 />
142+
</div>
143+
104144
</Most>
105145
, document.getElementById('app'));

0 commit comments

Comments
 (0)