1
1
import * as React from 'react' ;
2
2
import { render } from 'react-dom' ;
3
3
import '../../../../../src/xs/rx'
4
- import { pure , lift2 , X , xinput , fromEvent , traverse , fold } from '../../../../../src'
4
+ import { Applicative , lift2 , Semigroup , Functor , map , Traversable , FlatMap } from '../../../../../src/fantasy'
5
+ import { X } from '../../../../../src'
5
6
function xmount ( component , dom ) { render ( React . createFactory ( X ) ( { } , component ) , dom ) }
6
7
7
8
let mult = ( x :number , y : number ) => x * y
8
- let Xeg1 = lift2 ( mult ) ( pure ( 6 ) , pure ( 5 ) )
9
+ let Xeg1 = lift2 < "FantasyX" , number , number , number > ( mult ) ( Applicative . FantasyX . pure ( 6 ) , Applicative . FantasyX . pure ( 5 ) )
9
10
10
11
let ViewEg1 = props => < p className = "result" > { props . product } </ p >
11
12
12
- let Eg1 = Xeg1 . map ( a => ( { product : a } ) ) . apply ( ViewEg1 )
13
+ let Eg1 = Functor . FantasyX . map ( a => ( { product : a } ) , Xeg1 ) . apply ( ViewEg1 )
13
14
14
15
xmount ( < Eg1 /> , document . getElementById ( 'eg1' ) )
15
16
17
+ import { Xstream } from '../../../../../src/fantasy/xstream' ;
18
+
16
19
function strToInt ( x ) { return ~ ~ x }
20
+ type Intent = { type :string , value :number }
21
+ let XSinput1 = Xstream . fromEvent ( 'change' , 'n1' , '5' )
22
+ let XSinput2 = Xstream . fromEvent ( 'change' , 'n2' , '6' )
17
23
18
- let Xeg2 = lift2 ( mult ) (
19
- fromEvent ( 'change' , 'n1' , '5' ) . map ( strToInt ) ,
20
- fromEvent ( 'change' , 'n2' , '6' ) . map ( strToInt )
21
- )
24
+ let Xeg2 = lift2 < "Xstream" , number , number , number > ( mult ) (
25
+ Functor . Xstream . map ( strToInt , XSinput1 ) ,
26
+ Functor . Xstream . map ( strToInt , XSinput2 )
27
+ ) . toFantasyX ( )
28
+ . map ( x => ( { product : x } ) )
22
29
23
30
let ViewEg2 = props => < section >
24
- < p > < input type = "number" name = "n1" onChange = { props . actions . fromEvent } defaultValue = "5" /> </ p >
25
- < p > < input type = "number" name = "n2" onChange = { props . actions . fromEvent } defaultValue = "6" /> </ p >
26
- < p > < span className = "result" > { props . product } </ span > </ p >
27
- </ section >
31
+ < p > < input type = "number" name = "n1" onChange = { props . actions . fromEvent } defaultValue = "5" /> </ p >
32
+ < p > < input type = "number" name = "n2" onChange = { props . actions . fromEvent } defaultValue = "6" /> </ p >
33
+ < p > < span className = "result" > { props . product } </ span > </ p >
34
+ </ section >
28
35
29
- let Eg2 = Xeg2 . map ( a => ( { product : a } ) ) . apply ( ViewEg2 )
36
+ let Eg2 = Xeg2 . apply ( ViewEg2 )
30
37
31
38
xmount ( < Eg2 /> , document . getElementById ( 'eg2' ) )
32
39
33
- let Xeg3 = fromEvent ( 'change' , 'firstName' , 'Jichao' )
34
- . concat ( pure ( ' ' ) )
35
- . concat ( fromEvent ( 'change' , 'lastName' , 'Ouyang' ) )
36
-
40
+ let Xeg3 = Semigroup . Xstream . concat (
41
+ Semigroup . Xstream . concat (
42
+ Xstream . fromEvent ( 'change' , 'firstName' , 'Jichao' ) ,
43
+ Applicative . Xstream . pure ( ' ' )
44
+ ) ,
45
+ Xstream . fromEvent ( 'change' , 'lastName' , 'Ouyang' )
46
+ ) . toFantasyX ( )
37
47
let ViewEg3 = props => < section >
38
- < p > < input type = "text" name = "firstName" onChange = { props . actions . fromEvent } defaultValue = "Jichao" /> </ p >
39
- < p > < input type = "text" name = "lastName" onChange = { props . actions . fromEvent } defaultValue = "Ouyang" /> </ p >
40
- < p > < span className = "result" > { props . semigroup } </ span > </ p >
41
- </ section >
48
+ < p > < input type = "text" name = "firstName" onChange = { props . actions . fromEvent } defaultValue = "Jichao" /> </ p >
49
+ < p > < input type = "text" name = "lastName" onChange = { props . actions . fromEvent } defaultValue = "Ouyang" /> </ p >
50
+ < p > < span className = "result" > { props . semigroup } </ span > </ p >
51
+ </ section >
42
52
43
53
let Eg3 = Xeg3 . map ( a => ( { semigroup : a } ) ) . apply ( ViewEg3 )
44
54
@@ -48,10 +58,11 @@ function sum(list){
48
58
return list . reduce ( ( acc , x ) => acc + x , 0 )
49
59
}
50
60
let list = [ '1' , '2' , '3' , '4' , '5' , '6' , '7' ]
51
- let Xeg4 = traverse (
52
- ( defaultVal , index ) => ( fromEvent ( 'change' , 'traverse' + index , defaultVal ) ) ,
53
- list
54
- ) . map ( xs => xs . map ( strToInt ) )
61
+ let Xeg4 = Traversable . Array . traverse < 'Xstream' , string , string > ( 'Xstream' ) (
62
+ ( defaultVal , index ) => ( Xstream . fromEvent ( 'change' , 'traverse' + index , defaultVal ) ) ,
63
+ list
64
+ ) . toFantasyX ( )
65
+ . map ( xs => xs . map ( strToInt ) )
55
66
. map ( sum )
56
67
57
68
let ViewEg4 = props => < section >
@@ -67,91 +78,91 @@ let Eg4 = Xeg4.map(a=>({sum: a})).apply(ViewEg4)
67
78
xmount ( < Eg4 /> , document . getElementById ( 'eg4' ) )
68
79
69
80
function bmiCalc ( weight , height ) {
70
- return {
71
- weight : weight ,
72
- height : height ,
73
- result :fetch ( `https://gist.github.com.ru/jcouyang/edc3d175769e893b39e6c5be12a8526f?height=${ height } &weight=${ weight } ` )
74
- . then ( resp => resp . json ( ) )
75
- . then ( json => json . result )
76
- }
81
+ return fetch ( `https://gist.github.com.ru/jcouyang/edc3d175769e893b39e6c5be12a8526f?height=${ height } &weight=${ weight } ` )
82
+ . then ( resp => resp . json ( ) )
83
+ . then ( json => json . result )
77
84
}
78
85
79
- let Xeg5 = lift2 ( bmiCalc ) (
80
- fromEvent ( 'change' , 'weight' , '70' ) ,
81
- fromEvent ( 'change' , 'height' , '175' )
86
+ let xweigth = Xstream . fromEvent ( 'change' , 'weight' , '70' )
87
+ let xheight = Xstream . fromEvent ( 'change' , 'height' , '175' )
88
+
89
+ let promiseXstream = lift2 < "Xstream" , string , string , Promise < any > > ( bmiCalc ) (
90
+ xweigth ,
91
+ xheight
92
+ )
93
+
94
+ let Xeg5 = FlatMap . Xstream . flatMap ( Xstream . fromPromise , promiseXstream )
95
+ . toFantasyX ( )
96
+
97
+ let ViewEg5 = props => (
98
+ < div >
99
+ < label > Height: { props . height } cm
100
+ < input type = "range" name = "height" onChange = { props . actions . fromEvent } min = "150" max = "200" defaultValue = { props . height } />
101
+ </ label >
102
+ < label > Weight: { props . weight } kg
103
+ < input type = "range" name = "weight" onChange = { props . actions . fromEvent } min = "40" max = "100" defaultValue = { props . weight } />
104
+ </ label >
105
+ < p > HEALTH: < span > { props . health } </ span > </ p >
106
+ < p > BMI: < span className = "result" > { props . bmi } </ span > </ p >
107
+ </ div >
82
108
)
83
109
84
- let ViewEg5 = props => (
85
- < div >
86
- < label > Height: { props . height } cm
87
- < input type = "range" name = "height" onChange = { props . actions . fromEvent } min = "150" max = "200" defaultValue = { props . height } />
88
- </ label >
89
- < label > Weight: { props . weight } kg
90
- < input type = "range" name = "weight" onChange = { props . actions . fromEvent } min = "40" max = "100" defaultValue = { props . weight } />
91
- </ label >
92
- < p > HEALTH: < span > { props . health } </ span > </ p >
93
- < p > BMI: < span className = "result" > { props . bmi } </ span > </ p >
94
- </ div >
95
- )
96
-
97
- let Eg5 = Xeg5 . apply ( ViewEg5 )
110
+ let Eg5 = Xeg5 . apply ( ViewEg5 )
98
111
99
112
xmount ( < Eg5 /> , document . getElementById ( 'eg5' ) )
100
113
101
- let Xeg6 = fold (
102
- ( acc : number , i : number ) => acc + i ,
103
- 0 ,
104
- fromEvent ( 'click' , 'increment' ) . map ( x => 1 )
105
- )
114
+ let Xeg6 = Xstream . fromEvent ( 'click' , 'increment' )
115
+ . toFantasyX < { count : number } > ( )
116
+ . map ( x => 1 )
117
+ . foldS ( ( acc , a ) => {
118
+ return { count : ( acc . count || 0 ) + a } } )
106
119
107
120
let ViewEg6 = props => < p >
108
- < span className = "result" > { props . count } </ span >
109
- < input type = "button" name = "increment" value = "+1" onClick = { e => props . actions . fromEvent ( e ) } />
110
- </ p >
121
+ < span className = "result" > { props . count || 0 } </ span >
122
+ < input type = "button" name = "increment" value = "+1" onClick = { e => props . actions . fromEvent ( e ) } />
123
+ </ p >
111
124
112
- let Eg6 = Xeg6 . map ( a => ( { count : a } ) ) . apply ( ViewEg6 )
125
+ let Eg6 = Xeg6 . apply ( ViewEg6 )
113
126
114
127
xmount ( < Eg6 /> , document . getElementById ( 'eg6' ) )
115
128
116
- let Xeg7 = fold (
117
- ( acc :number , i : number ) => acc + i ,
118
- 0 ,
119
- fromEvent ( 'click' , 'increment' ) . map ( x => 1 )
120
- . merge (
121
- fromEvent ( 'click' , 'decrement' ) . map ( x => - 1 )
122
- )
123
- )
129
+ let Xeg7 = Xstream . fromEvent ( 'click' , 'decrement' )
130
+ . toFantasyX < { count :number } > ( )
131
+ . map ( x => - 1 )
132
+ . foldS ( ( acc , a ) => {
133
+ return { count : ( acc . count || 0 ) + a } } )
124
134
125
- let ViewEg7 = props => < p >
126
- < input type = "button" name = "decrement" value = "-" onClick = { e => props . actions . fromEvent ( e ) } />
127
- < span className = "result" > { props . count } </ span >
128
- < input type = "button" name = "increment" value = "+" onClick = { e => props . actions . fromEvent ( e ) } />
129
- </ p >
135
+ let ViewEg7 = props => < p >
136
+ < input type = "button" name = "decrement" value = "-" onClick = { e => props . actions . fromEvent ( e ) } />
137
+ < span className = "result" > { props . count || 0 } </ span >
138
+ < input type = "button" name = "increment" value = "+" onClick = { e => props . actions . fromEvent ( e ) } />
139
+ </ p >
130
140
131
- let Eg7 = Xeg7 . map ( a => ( { count : a } ) ) . apply ( ViewEg7 )
141
+ let Eg7 = Xeg7 . merge ( Xeg6 ) . apply ( ViewEg7 )
132
142
133
143
xmount ( < Eg7 /> , document . getElementById ( 'eg7' ) )
134
144
135
145
const actions = [ '-1' , '+1' , 'reset' ]
136
- let Xeg8 = fold (
137
- ( acc , i ) => {
138
- switch ( i ) {
139
- case '-1' : return acc - 1
140
- case '+1' : return acc + 1
141
- case 'reset' : return 0
142
- default : acc
146
+ let Xeg8 =
147
+ actions . map ( ( action ) => Xstream . fromEvent ( 'click' , action ) . toFantasyX < { count :number } > ( ) )
148
+ . reduce ( ( acc , a ) => acc . merge ( a ) )
149
+ . foldS ( ( acc , i ) => {
150
+ acc . count = acc . count || 0
151
+ switch ( i ) {
152
+ case '-1' : return { count : acc . count - 1 }
153
+ case '+1' : return { count : acc . count + 1 }
154
+ case 'reset' : return { count : 0 }
155
+ default : acc
156
+ }
143
157
}
144
- } ,
145
- 0 ,
146
- actions . map ( ( action ) => fromEvent ( 'click' , action ) )
147
- . reduce ( ( acc , a ) => acc . merge ( a ) ) )
158
+ )
148
159
149
160
let ViewEg8 = props => < p >
150
161
< span className = "result" > { props . count } </ span >
151
162
{ actions . map ( action =>
152
163
< input type = "button" name = { action } value = { action } onClick = { e => props . actions . fromEvent ( e ) } /> ) }
153
164
</ p >
154
165
155
- let Eg8 = Xeg8 . map ( a => ( { count : a } ) ) . apply ( ViewEg8 )
166
+ let Eg8 = Xeg8 . apply ( ViewEg8 )
156
167
157
168
xmount ( < Eg8 /> , document . getElementById ( 'eg8' ) )
0 commit comments