|
12 | 12 |
|
13 | 13 | Monad, Functional Programming features for Golang |
14 | 14 |
|
| 15 | +Active Branches: |
| 16 | + |
| 17 | +For Generics version(>=go1.18):[generics](https://github.com/TeaEntityLab/fpGo/tree/generics) |
| 18 | + |
| 19 | +For NonGenerics version(<=go1.17):[non-generics](https://github.com/TeaEntityLab/fpGo/tree/non_generic) |
| 20 | + |
15 | 21 | # Why |
16 | 22 |
|
17 | 23 | I love functional programing, Rx-style coding, and Optional usages. |
@@ -40,6 +46,7 @@ Thus I implemented fpGo. I hope you would like it :) |
40 | 46 |
|
41 | 47 | * PythonicGenerator-like Coroutine(yield/yieldFrom) |
42 | 48 |
|
| 49 | +* Akka/Erlang-like Actor model(send/receive/spawn/states) |
43 | 50 |
|
44 | 51 | # Usage |
45 | 52 |
|
@@ -131,6 +138,79 @@ for _, v := range s.ToArray() { |
131 | 138 | fmt.Println(tempString) // tempString would be "1234" |
132 | 139 | ``` |
133 | 140 |
|
| 141 | +## Actor (inspired by Akka/Erlang) |
| 142 | + |
| 143 | +Example: |
| 144 | + |
| 145 | +```go |
| 146 | +actual := 0 |
| 147 | +// Channel for results |
| 148 | +resultChannel := make(chan interface{}, 1) |
| 149 | +// Message CMDs |
| 150 | +cmdSpawn := "spawn" |
| 151 | +cmdShutdown := "shutdown" |
| 152 | +// Testee |
| 153 | +actorRoot := Actor.New(func(self *ActorDef, input interface{}) { |
| 154 | + // SPAWN: for ROOT |
| 155 | + if input == cmdSpawn { |
| 156 | + self.Spawn(func(self *ActorDef, input interface{}) { |
| 157 | + // SHUTDOWN: for Children |
| 158 | + if input == cmdShutdown { |
| 159 | + self.Close() |
| 160 | + return |
| 161 | + } |
| 162 | + |
| 163 | + // INT cases: Children |
| 164 | + val, _ := Maybe.Just(input).ToInt() |
| 165 | + resultChannel <- val * 10 |
| 166 | + }) |
| 167 | + return |
| 168 | + } |
| 169 | + // SHUTDOWN: for ROOT |
| 170 | + if input == cmdShutdown { |
| 171 | + for _, child := range self.children { |
| 172 | + child.Send(cmdShutdown) |
| 173 | + } |
| 174 | + self.Close() |
| 175 | + |
| 176 | + close(resultChannel) |
| 177 | + return |
| 178 | + } |
| 179 | + |
| 180 | + // INT cases: ROOT |
| 181 | + intVal, _ := Maybe.Just(input).ToInt() |
| 182 | + if intVal > 0 { |
| 183 | + for _, child := range self.children { |
| 184 | + child.Send(intVal) |
| 185 | + } |
| 186 | + } |
| 187 | +}) |
| 188 | + |
| 189 | +// Sequential Send messages(async) |
| 190 | +go func() { |
| 191 | + actorRoot.Send(cmdSpawn) |
| 192 | + actorRoot.Send(10) |
| 193 | + actorRoot.Send(cmdSpawn) |
| 194 | + actorRoot.Send(20) |
| 195 | + actorRoot.Send(cmdSpawn) |
| 196 | + actorRoot.Send(30) |
| 197 | +}() |
| 198 | + |
| 199 | +i := 0 |
| 200 | +for val := range resultChannel { |
| 201 | + intVal, _ := Maybe.Just(val).ToInt() |
| 202 | + actual += intVal |
| 203 | + |
| 204 | + i++ |
| 205 | + if i == 5 { |
| 206 | + go actorRoot.Send(cmdShutdown) |
| 207 | + } |
| 208 | +} |
| 209 | + |
| 210 | +// Result would be 1400 (=10*10+20*10+20*10+30*10+30*10+30*10) |
| 211 | +fmt.Println(actual) |
| 212 | +``` |
| 213 | + |
134 | 214 | ## Compose |
135 | 215 |
|
136 | 216 | Example: |
|
0 commit comments