rx.km 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. ## Effect Types
  2. /// Observable[T,E] represents an effect that may return 0/finite/infinite
  3. /// T values, or throw an E error half-way, synchronously or asynchronously.
  4. type Observable [out T = unit, out E = never]
  5. native; // rx.Observable
  6. /// Async[T,E] represents an effect that may return a T value,
  7. /// or throw an E error, synchronously or asynchronously.
  8. /// It is a subtype of Observable[T,E] and can be regarded as a lazy Promise.
  9. type Async [out T = unit, out E = never]
  10. protected
  11. Observable[T,E];
  12. /// Sync[T] represents an effect that returns a T value synchronously.
  13. /// It is a subtype of Async[T]. Different from general Async, an Sync
  14. /// is guaranteed synchronous and cannot be cancelled half-way.
  15. /// There is a `sync` function, which can be used to concatenate
  16. /// multiple Sync effects into a single Sync effect.
  17. type Sync [out T = unit]
  18. protected
  19. Async[T];
  20. /// Source[T] represents an effect that subscribes to a discrete data source.
  21. /// It is a subtype of Observable[T]. Different from general Observable, a Source
  22. /// never terminates.
  23. type Source [out T]
  24. protected
  25. Observable[T];
  26. /// Computed[T] represents an effect that subscribes to a continuous data source.
  27. /// It is a subtype of Source[T]. Different from general Source, a Computed
  28. /// holds a current value and always produces its current value synchronously
  29. /// as its first value.
  30. type Computed [out T]
  31. protected
  32. Source[T];
  33. ## Wired Components
  34. /// Sink[T] accepts values of type T.
  35. type Sink [in T]
  36. native; // rx.Sink
  37. /// Bus[T] accepts values of type T and provides accepted T values,
  38. /// similar to the concept of Subject in ReactiveX.
  39. type Bus[T]
  40. protected Sink[T]; // rx.Bus
  41. /// Reactive[T] represents a reactively mutable T value,
  42. /// similar to the concept of BehaviourSubject in ReactiveX.
  43. type Reactive[T]
  44. protected Bus[T]; // rx.Reactive
  45. /// ReactiveEntity[T] is a subtype of Reactive[T],
  46. /// which represents an independent reactive entity holding a mutable T value.
  47. /// That is, different from the general concept of Reactive,
  48. /// a ReactiveEntity is not derived from other Reactive values.
  49. /// As a consequence, a ReactiveEntity can store snapshots of previous values
  50. /// so that it is possible to perform undo/redo operations on it.
  51. type ReactiveEntity[T]
  52. protected Reactive[T]; // rx.ReactiveEntity
  53. ## Synchronization Types
  54. type Mutex [out T]
  55. native;
  56. ## Mutable Containers
  57. type Buffer native; // rx.Buffer
  58. ## Wired Components Operations
  59. export function connect:[T]
  60. &(Source[T], Sink[T]) => Async[never]
  61. native 'connect';
  62. export function connect:[T]
  63. &(Bus[T], Sink[T]) => Async[never]
  64. &(bus, sink) => ({watch(bus)} connect sink);
  65. export function connect:[T]
  66. &(Source[T], &(T) => Async) => Async[never]
  67. &(source, receiver) => (source connect {Callback(receiver)});
  68. export function connect:[T]
  69. &(Bus[T], &(T) => Async) => Async[never]
  70. &(bus, receiver) => ({watch(bus)} connect {Callback(receiver)});
  71. export function connect:
  72. &(Source[unit], Async) => Async[never]
  73. &(source, receiver) => (source connect {Callback::[unit](&() => receiver)});
  74. export function connect:
  75. &(Bus[unit], Async) => Async[never]
  76. &(bus, receiver) => (bus connect {Callback::[unit](&() => receiver)});
  77. export function <- :
  78. [T] &(Sink[T], T) => Sync
  79. native 'sink-write';
  80. export function adapt:[A,B]
  81. &(Sink[A], &(B) => A) => Sink[B]
  82. native 'sink-adapt';
  83. export function watch:[T]
  84. &(Bus[T]) => Source[T]
  85. native 'bus-watch';
  86. export function watch:[T]
  87. &(Reactive[T]) => Computed[T]
  88. native 'bus-watch';
  89. export function update:[T]
  90. &(Reactive[T], &(T) => T) => Sync
  91. native 'reactive-update';
  92. export function adapt:[A,B]
  93. &(Reactive[A], &(A) => &(B) => A) => Sink[B]
  94. native 'reactive-adapt';
  95. function morph:[A,B]
  96. &(Reactive[A], (&(A) => &(B) => A), (&(A) => B)) => Reactive[B]
  97. native 'reactive-morph';
  98. export function morph:[A,B]
  99. &(Reactive[A], { in: &(A) => &(B) => A, out: &(A) => B }) => Reactive[B]
  100. &(r, f) => { morph (r, f.in, f.out) };
  101. export function proj:[A,B]
  102. &(Reactive[A], &(A) => ProjRef[A,B]) => Reactive[B]
  103. &(r, ref) => (r morph {
  104. in: (&a => &b => (a.{ref} <- b)) .[&(A) => &(B) => A],
  105. out: (&a => a.{ref}.{->}) .[&(A) => B]
  106. });
  107. export function -> :
  108. [T] &(Reactive[T]) => Sync[T]
  109. native 'reactive-read';
  110. // TODO: should provide record instead of tuple
  111. export function consume:[T,X]
  112. &(Reactive[FlexList[T]], &(FlexListKey,Computed[Number],Reactive[T]) => Computed[X]) => Computed[List[X]]
  113. native 'reactive-flex-consume';
  114. export function Blackhole:
  115. &() => Sink[any]
  116. native 'Blackhole';
  117. export function Callback:[T]
  118. &(&(T) => Async) => Sink[T]
  119. native 'Callback';
  120. export function Bus:[T]
  121. &() => Sync[Bus[T]]
  122. native 'create-bus';
  123. export function Reactive:[T]
  124. &(T) => Sync[ReactiveEntity[T]]
  125. native 'create-reactive';
  126. ## Mutable Containers Operations
  127. // TODO
  128. ## Locks Operations
  129. export function Mutex: [T, K < Observable[any,any]]
  130. &(T, &(Mutex[T]) => K) => K
  131. native 'mutex';
  132. export function lock: [T, K < Observable[any]]
  133. &(Mutex[T], &(T) => K) => K
  134. native 'mutex-lock';
  135. ## Effect Constructors
  136. export function Source:[T]
  137. &(Observable[T]) => Source[T]
  138. native 'as-source';
  139. export function Computed:[A,B,X]
  140. &((Computed[A],Computed[B]), &(A,B) => X) => Computed[X]
  141. native 'computed';
  142. export function Computed:[A,B,C,X]
  143. &((Computed[A],Computed[B],Computed[C]), &(A,B,C) => X) => Computed[X]
  144. native 'computed';
  145. export function Computed:[A,B,C,D,X]
  146. &((Computed[A],Computed[B],Computed[C],Computed[D]), &(A,B,C,D) => X) => Computed[X]
  147. native 'computed';
  148. export function with: [A < Observable[any,any]]
  149. &(A, Async) => A
  150. native 'with';
  151. export function gen-random:
  152. &() => Sync[NormalFloat]
  153. native 'gen-random';
  154. export function gen-monotonic-id:
  155. &() => Sync[Number]
  156. native 'gen-monotonic-id';
  157. export function gen-monotonic-id-string:
  158. &() => Sync[String]
  159. native 'gen-monotonic-id-string';
  160. export function crash:
  161. &(String) => Sync[never]
  162. native 'crash';
  163. export function crash:
  164. &(Error) => Sync[never]
  165. native 'crash';
  166. /// go(f) returns an action that evaluates f() in a separate goroutine.
  167. export function go:[T]
  168. &(&() => T) => Async[T]
  169. native 'go-thunk';
  170. /// go(seq) returns an action that iterates seq in a separate goroutine.
  171. export function go:[T]
  172. &(Seq[T]) => Observable[T]
  173. native 'go-seq';
  174. export const Noop: Sync :=
  175. { yield () };
  176. export function yield:[T]
  177. &(T) => Sync[T]
  178. native 'yield';
  179. export function yield*:[T]
  180. &(Seq[T]) => Observable[T]
  181. native 'yield*-seq';
  182. export function yield*:[T]
  183. &(List[T]) => Observable[T]
  184. native 'yield*-array';
  185. export function not:
  186. &(Computed[Bool]) => Computed[Bool]
  187. &(p) => p.{map(not)};
  188. export function and:
  189. &(Computed[Bool], Computed[Bool]) => Computed[Bool]
  190. &(p,q) => { Computed ((p,q), &(p,q) => (p and q)) };
  191. export function or:
  192. &(Computed[Bool], Computed[Bool]) => Computed[Bool]
  193. &(p,q) => { Computed ((p,q), &(p,q) => (p or q)) };
  194. export function start-with:[T,E]
  195. &(Observable[T,E], List[T]) => Observable[T,E]
  196. native 'start-with';
  197. export function Computed:[T]
  198. &(Source[T], { beginning: List[T] }) => Computed[T]
  199. native 'start-with-to-computed';
  200. export function wait:
  201. & { timeout: Number } => Async
  202. native 'wait';
  203. export function tick:
  204. & { interval: Number } => Source[unit]
  205. native 'tick';
  206. ## Effect Operators
  207. export function ->:
  208. [T] &(Computed[T]) => Sync[T]
  209. native 'computed-read';
  210. export function take-one-as-single:[T,E]
  211. &(Observable[T,E]) => Async[Maybe[T],E]
  212. native 'take-one-as-single';
  213. export function wait-complete:[E]
  214. &(Observable[unit,E]) => Async[unit,E]
  215. native 'wait-complete';
  216. export function forever:[E]
  217. &(Observable[unit,E]) => Async[never,E]
  218. native 'forever';
  219. /// This function has two kinds of definitions:
  220. /// 1. then(a1, r1 => a2) returns an action that performs a1 first and then
  221. /// transforms r1 (the result of a1) into a2 and performs a2.
  222. /// 2. then(a1, a2) returns an action that performs a1 and then performs a2.
  223. /// In both cases, the returned action returns the result of a2.
  224. /// Moreover, this function has an alias called `await`, which is intended
  225. /// to be used within Flat CPS expressions.
  226. ///
  227. export function then:[A,B,E]
  228. &(Async[A,E], &(A) => Async[B,E]) => Async[B,E]
  229. native 'then';
  230. export function then:[A,B,E]
  231. &(Async[A,E], &(A) => Observable[B,E]) => Observable[B,E]
  232. native 'then';
  233. export function then:[A,B]
  234. &(Async[A], &(A) => Source[B]) => Source[B]
  235. native 'then';
  236. export function then:[E,B]
  237. &(Async[unit,E], Async[B,E]) => Async[B,E]
  238. native 'then-shortcut';
  239. export function then:[E,B]
  240. &(Async[unit,E], Observable[B,E]) => Observable[B,E]
  241. native 'then-shortcut';
  242. export function then:[B]
  243. &(Async, Source[B]) => Source[B]
  244. native 'then-shortcut';
  245. alias await := then;
  246. export function sync: [A, K < Observable[any,any]]
  247. &(Sync[A], &(A) => K) => K
  248. native 'sync';
  249. export function sync: [K < Observable[any,any]]
  250. &(Sync, K) => K
  251. native 'sync-shortcut';
  252. export function catch:[T,E,F]
  253. &(Async[T,E], &(E) => Async[T,F]) => Async[T,F]
  254. native 'catch';
  255. export function catch:[T,E,F]
  256. &(Observable[T,E], &(E) => Observable[T,F]) => Observable[T,F]
  257. native 'catch';
  258. export function catch-retry:[T,E]
  259. &(Async[T,E], &(E) => Async[Bool]) => Async[T,E]
  260. native 'catch-retry';
  261. export function catch-retry:[T,E]
  262. &(Observable[T,E], &(E) => Async[Bool]) => Observable[T,E]
  263. native 'catch-retry';
  264. export function catch-throw:[T,E,F]
  265. &(Async[T,E], &(E) => F) => Async[T,F]
  266. native 'catch-throw';
  267. export function catch-throw:[T,E,F]
  268. &(Observable[T,E], &(E) => F) => Observable[T,F]
  269. native 'catch-throw';
  270. export function crash-on-error:[T]
  271. &(Async[T,Error]) => Async[T]
  272. &(action) => action.{ catch &(err) => { crash err } };
  273. export function crash-on-error:[T]
  274. &(Observable[T,Error]) => Observable[T]
  275. &(action) => action.{ catch &(err) => { crash err } };
  276. export function throw:[E]
  277. &(E) => Async[never,E]
  278. native 'throw';
  279. export function map:[A,B,E]
  280. &(Async[A,E], &(A) => B) => Async[B,E]
  281. native 'observable-map';
  282. export function map:[A,B,E]
  283. &(Observable[A,E], &(A) => B) => Observable[B,E]
  284. native 'observable-map';
  285. export function map:[A,B]
  286. &(Source[A], &(A) => B) => Source[B]
  287. native 'observable-map';
  288. export function map:[A,B]
  289. &(Computed[A], &(A) => B) => Computed[B]
  290. native 'computed-map';
  291. export function map-to:[A,B,E]
  292. &(Async[A,E], B) => Async[B,E]
  293. &(e,v) => e.{map(&(_) => v)};
  294. export function map-to:[A,B,E]
  295. &(Observable[A,E], B) => Observable[B,E]
  296. &(e,v) => e.{map(&(_) => v)};
  297. export function filter:[T,E]
  298. &(Observable[T,E], &(T) => Bool) => Observable[T,E]
  299. native 'observable-filter';
  300. export function filter:[T]
  301. &(Source[T], &(T) => Bool) => Source[T]
  302. native 'observable-filter';
  303. export function filter-map:[A,B,E]
  304. &(Observable[A,E], &(A) => Maybe[B]) => Observable[B,E]
  305. native 'observable-filter-map';
  306. export function reduce:[T,A,E]
  307. &(Observable[T,E], (A, &(A,T) => A)) => Async[A,E]
  308. native 'observable-reduce';
  309. export function scan:[T,A,E]
  310. &(Observable[T,E], (A, &(A,T) => A)) => Observable[A,E]
  311. native 'observable-scan';
  312. export function scan:[T,A]
  313. &(Source[T], (A, &(A,T) => A)) => Source[A]
  314. native 'observable-scan';
  315. export function debounce:[T,E]
  316. &(Observable[T,E], Number) => Observable[T,E]
  317. native 'debounce-time';
  318. export function debounce:[T]
  319. &(Source[T], Number) => Source[T]
  320. native 'debounce-time';
  321. export function merge-map:[A,B,E]
  322. &(Observable[A,E], &(A) => Observable[B,E]) => Observable[B,E]
  323. native 'merge-map';
  324. export function concat-map:[A,B,E]
  325. &(Observable[A,E], &(A) => Observable[B,E]) => Observable[B,E]
  326. native 'concat-map';
  327. export function concat-map:[A,B]
  328. &(Source[A], &(A) => Observable[B]) => Source[B]
  329. native 'concat-map';
  330. export function mix-map:[A,B,E]
  331. &(Observable[A,E], Number, &(A) => Observable[B,E]) => Observable[B,E]
  332. native 'mix-map';
  333. export function switch-map:[A,B,E]
  334. &(Observable[A,E], &(A) => Observable[B,E]) => Observable[B,E]
  335. native 'switch-map';
  336. export function switch-map:[A,B]
  337. &(Source[A], &(A) => Observable[B]) => Source[B]
  338. native 'switch-map';
  339. export function switch-map:[A,B]
  340. &(Computed[A], &(A) => Computed[B]) => Computed[B]
  341. native 'switch-map-computed';
  342. export function merge:[T,E]
  343. &(List[Observable[T,E]]) => Observable[T,E]
  344. native 'observable-merge';
  345. export function merge:
  346. &(List[Async[never]]) => Async[never]
  347. native 'observable-merge';
  348. export function merge:[T]
  349. &(List[Source[T]]) => Source[T]
  350. native 'observable-merge';
  351. export function concat:[T,E]
  352. &(List[Observable[T,E]]) => Observable[T,E]
  353. native 'observable-concat';
  354. export function distinct-until-changed:
  355. [T,E] { = : Op=[T] }
  356. &(Observable[T,E]) => Observable[T,E]
  357. &(a) => { distinct-until-changed (a, =) };
  358. export function distinct-until-changed:
  359. [T] { = : Op=[T] }
  360. &(Source[T]) => Source[T]
  361. &(a) => { distinct-until-changed (a, =) };
  362. export function distinct-until-changed:[T,E]
  363. &(Observable[T,E], &(T,T) => Bool) => Observable[T,E]
  364. native 'distinct-until-changed';
  365. export function distinct-until-changed:[T]
  366. &(Source[T], &(T,T) => Bool) => Source[T]
  367. native 'distinct-until-changed';
  368. export function with-latest-from:[A,B,E]
  369. &(Observable[A,E], Observable[B,E]) => Observable[(A,Maybe[B]),E]
  370. native 'with-latest-from';
  371. export function with-latest-from:[A,B,E]
  372. &(Observable[A,E], Reactive[B]) => Observable[(A,B),E]
  373. native 'with-latest-from-reactive';
  374. export function with-latest-from:[A,B]
  375. &(Source[A], Reactive[B]) => Source[(A,B)]
  376. native 'with-latest-from-reactive';
  377. export function with-latest-from:[A,B]
  378. &(Computed[A], Reactive[B]) => Computed[(A,B)]
  379. native 'with-latest-from-reactive-to-computed';
  380. export function combine-latest:[A,B,E]
  381. &(Observable[A,E], Observable[B,E]) =>
  382. Observable[(Maybe[A],Maybe[B]),E]
  383. native 'combine-latest';
  384. export function combine-latest:[A,B,C,E]
  385. &(Observable[A,E],Observable[B,E],Observable[C,E]) =>
  386. Observable[(Maybe[A],Maybe[B],Maybe[C]),E]
  387. native 'combine-latest';
  388. export function combine-latest:[A,B,C,D,E]
  389. &(Observable[A,E],Observable[B,E],Observable[C,E],Observable[D,E]) =>
  390. Observable[(Maybe[A],Maybe[B],Maybe[C],Maybe[D]),E]
  391. native 'combine-latest';
  392. export function combine-latest*:[A,B,E]
  393. &(Observable[A,E],Observable[B,E]) => Observable[(A,B),E]
  394. native 'combine-latest*';
  395. export function combine-latest*:[A,B,C,E]
  396. &(Observable[A,E],Observable[B,E],Observable[C,E]) => Observable[(A,B,C),E]
  397. native 'combine-latest*';
  398. export function combine-latest*:[A,B,C,D,E]
  399. &(Observable[A,E],Observable[B,E],Observable[C,E],Observable[D,E]) => Observable[(A,B,C,D),E]
  400. native 'combine-latest*';
  401. export function combine-latest*:[T,E]
  402. &(List[Observable[T,E]]) => Observable[List[T],E]
  403. native 'combine-latest*-array';
  404. export function combine:[A,B]
  405. &(Computed[A],Computed[B]) => Computed[(A,B)]
  406. native 'combine';
  407. export function combine:[A,B,C]
  408. &(Computed[A],Computed[B],Computed[C]) => Computed[(A,B,C)]
  409. native 'combine';
  410. export function combine:[A,B,C,D]
  411. &(Computed[A],Computed[B],Computed[C],Computed[D]) => Computed[(A,B,C,D)]
  412. native 'combine';
  413. export function combine:[T]
  414. &(List[Computed[T]]) => Computed[List[T]]
  415. native 'combine-array';