containers.km 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. ## Container Types
  2. type Seq [out T]
  3. native; // container.Seq
  4. type List [out T]
  5. native; // container.List, ([] T)
  6. type FlexList [out T]
  7. native; // container.FlexList
  8. type Set [out T]
  9. native; // container.Set
  10. type Map [out K, out V]
  11. native; // container.Map
  12. type Queue [out T]
  13. native; // container.Queue
  14. type PriorityQueue [out T]
  15. native; // container.PriorityQueue
  16. ## Auxiliary Types for Containers
  17. type FlexListKey
  18. String;
  19. ## Container Operations
  20. /* Functions for Seq[T] */
  21. export function List:[T]
  22. &(Seq[T]) => List[T]
  23. native 'seq-collect';
  24. export function shift:[T]
  25. &(Seq[T]) => Maybe[(T,Seq[T])]
  26. native 'seq-shift';
  27. export function is-nil:[T]
  28. &(Seq[T]) => Bool
  29. &(seq) => { not seq.{shift}.{Bool} };
  30. export const Nil:
  31. Seq[never]
  32. := native 'seq-nil';
  33. export function cons:[T]
  34. &(T,Seq[T]) => Seq[T]
  35. native 'seq-cons';
  36. export function Seq:
  37. & { from: Number, to: Number } => Seq[Number]
  38. native 'seq-range-inclusive';
  39. export function Seq:
  40. & { initial: Number, count: Number } => Seq[Number]
  41. native 'seq-range-count';
  42. export function map:[A,B]
  43. &(Seq[A], &(A) => B) => Seq[B]
  44. native 'seq-map';
  45. export function filter-map:[A,B]
  46. &(Seq[A], &(A) => Maybe[B]) => Seq[B]
  47. native 'seq-filter-map';
  48. export function filter:[T]
  49. &(Seq[T], &(T) => Bool) => Seq[T]
  50. native 'seq-filter';
  51. export function flat-map:[A,B]
  52. &(Seq[A], &(A) => Seq[B]) => Seq[B]
  53. native 'seq-flat-map';
  54. export function scan:[T,A]
  55. &(Seq[T], A, &(A,T) => A) => Seq[A]
  56. native 'seq-scan';
  57. export function scan:[T,A]
  58. &(Seq[T], (A, &(A,T) => A)) => Seq[A]
  59. &(seq, opts) => let (init,f) := opts, { scan (seq,init,f) };
  60. export function reduce:[T,A]
  61. &(Seq[T], A, &(A,T) => A) => A
  62. native 'seq-reduce';
  63. export function reduce:[T,A]
  64. &(Seq[T], (A, &(A,T) => A)) => A
  65. &(seq, opts) => let (init,f) := opts, { reduce (seq,init,f) };
  66. export function apply-all:[T]
  67. &(T, Seq[&(T) => T]) => T
  68. &(init, @f) => @f.{ reduce (init, &(x,f) => { f(x) }) };
  69. export function some:[T]
  70. &(Seq[T], &(T) => Bool) => Bool
  71. native 'seq-some';
  72. export function every:[T]
  73. &(Seq[T], &(T) => Bool) => Bool
  74. native 'seq-every';
  75. export function chunk:[T]
  76. &(Seq[T], Number) => Seq[List[T]]
  77. native 'seq-chunk';
  78. export function concat:[T]
  79. &(List[Seq[T]]) => Seq[T]
  80. &(array) => array.{Seq}.{flat-map(&(items) => items)};
  81. /* Functions of List[T] */
  82. export function Seq:[T]
  83. &(List[T]) => Seq[T]
  84. native 'list-iterate';
  85. export function length:[T]
  86. &(List[T]) => Number
  87. native 'list-length';
  88. export function reverse:[T]
  89. &(List[T]) => List[T]
  90. native 'list-reverse';
  91. export function shift:[T]
  92. &(List[T]) => Maybe[(T,List[T])]
  93. native 'list-shift';
  94. export function pop:[T]
  95. &(List[T]) => Maybe[(List[T],T)]
  96. native 'list-pop';
  97. export function unshift:[T]
  98. &(List[T]) => List[T]
  99. native 'list-unshift';
  100. export function unpop:[T]
  101. &(List[T]) => List[T]
  102. native 'list-unpop';
  103. export function map:[A,B]
  104. &(List[A], &(A) => B) => List[B]
  105. &(list, f) => { Seq list } .{ map f } .{ List };
  106. export function filter:[T]
  107. &(List[T], &(T) => Bool) => List[T]
  108. &(list, f) => { Seq list } .{ filter f } .{ List };
  109. export function reduce:[T,A]
  110. &(List[T], (A, &(A,T) => A)) => A
  111. &(list, opts) => { Seq list } .{ reduce opts };
  112. export function scan:[T,A]
  113. &(List[T], (A, &(A,T) => A)) => List[A]
  114. &(list, opts) => { Seq list } .{ scan opts } .{ List };
  115. export function some:[T]
  116. &(List[T], &(T) => Bool) => Bool
  117. &(list, p) => ({ Seq list } some p);
  118. export function every:[T]
  119. &(List[T], &(T) => Bool) => Bool
  120. &(list, p) => ({ Seq list } every p);
  121. /* Functions of Set[T] */
  122. export function new-set:[T]
  123. &(&(T,T) => Ordering, List[T]) => Set[T]
  124. native 'new-set';
  125. export function has:[T]
  126. &(Set[T], T) => Bool
  127. native 'set-has';
  128. /* Functions of Map[K,V] */
  129. export function Map:[T]
  130. &(List[(String,T)]) => Map[String,T]
  131. native 'create-map-str';
  132. export function List:[K,V]
  133. &(Map[K,V]) => List[(K,V)]
  134. native 'map-entries';
  135. export function get:[K,V]
  136. &(Map[K,V], K) => Maybe[V]
  137. native 'map-get';
  138. export function get!:[K,V]
  139. &(Map[K,V], K) => V
  140. native 'map-get!';
  141. export function insert:[K,V]
  142. &(Map[K,V], (K, V)) => Maybe[Map[K,V]]
  143. native 'map-insert';
  144. export function insert*:[K,V]
  145. &(Map[K,V], (K, V)) => Map[K,V]
  146. native 'map-insert*';
  147. export function delete:[K,V]
  148. &(Map[K,V], K) => Maybe[(V,Map[K,V])]
  149. native 'map-delete';
  150. export function delete*:[K,V]
  151. &(Map[K,V], K) => Map[K,V]
  152. native 'map-delete*';
  153. /* Functions for FlexList[T] */
  154. export function FlexList:[T]
  155. &(List[T], &(T) => FlexListKey) => FlexList[T]
  156. native 'create-flex';
  157. export function FlexList:[T]
  158. &() => FlexList[T]
  159. native 'create-flex-empty';
  160. export function Seq:[T]
  161. &(FlexList[T]) => Seq[(FlexListKey,T)]
  162. native 'flex-iterate';
  163. export function length:[T]
  164. &(FlexList[T]) => Number
  165. native 'flex-length';
  166. export function has:[T]
  167. &(FlexList[T], FlexListKey) => Bool
  168. native 'flex-has';
  169. export function get:[T]
  170. &(FlexList[T], FlexListKey) => T
  171. native 'flex-get';
  172. export function update:[T]
  173. &(FlexList[T], FlexListKey, &(T) => T) => FlexList[T]
  174. native 'flex-update';
  175. export function delete:[T]
  176. &(FlexList[T], FlexListKey) => FlexList[T]
  177. native 'flex-delete';
  178. export function prepend:[T]
  179. &(FlexList[T], (FlexListKey,T)) => FlexList[T]
  180. native 'flex-prepend';
  181. export function append:[T]
  182. &(FlexList[T], (FlexListKey,T)) => FlexList[T]
  183. native 'flex-append';
  184. export function insert:[T]
  185. &(FlexList[T], {before:FlexListKey}, (FlexListKey,T)) => FlexList[T]
  186. native 'flex-insert-before';
  187. export function insert:[T]
  188. &(FlexList[T], {after:FlexListKey}, (FlexListKey,T)) => FlexList[T]
  189. native 'flex-insert-after';
  190. export function move:[T]
  191. &(FlexList[T], FlexListKey, {before:FlexListKey}) => FlexList[T]
  192. native 'flex-move-before';
  193. export function move:[T]
  194. &(FlexList[T], FlexListKey, {after:FlexListKey}) => FlexList[T]
  195. native 'flex-move-after';
  196. export function move-up:[T]
  197. &(FlexList[T], FlexListKey) => FlexList[T]
  198. native 'flex-move-up';
  199. export function move-down:[T]
  200. &(FlexList[T], FlexListKey) => FlexList[T]
  201. native 'flex-move-down';
  202. export function swap:[T]
  203. &(FlexList[T], FlexListKey, FlexListKey) => FlexList[T]
  204. native 'flex-swap';
  205. // TODO: type ListItemIndexWatch protected Observable[Number]
  206. export function is-first-in:[T]
  207. &(Computed[Number], Reactive[FlexList[T]]) => Computed[Bool]
  208. &(@index, _) =>
  209. @index
  210. . { map &(index) => (index = 0) };
  211. export function is-last-in:[T]
  212. &(Computed[Number], Reactive[FlexList[T]]) => Computed[Bool]
  213. &(@index,@list) =>
  214. let @length := ({ watch @list } map &(list) => list.{length}),
  215. { combine (@index, @length) }
  216. . { map &(index,length) => (index = (length - 1)) };
  217. export function update:[T]
  218. &(Reactive[FlexList[T]], FlexListKey, &(T) => T) => Sync
  219. &(@list,key,f) => @list.{ update &(list) => {update(list,key,f)} };
  220. export function delete:[T]
  221. &(Reactive[FlexList[T]], FlexListKey) => Sync
  222. &(@list,key) => @list.{ update &(list) => {delete(list,key)} };
  223. export function prepend:[T]
  224. &(Reactive[FlexList[T]], (FlexListKey,T)) => Sync
  225. &(@list,entry) => @list.{ update &(list) => {prepend(list,entry)} };
  226. export function append:[T]
  227. &(Reactive[FlexList[T]], (FlexListKey,T)) => Sync
  228. &(@list,entry) => @list.{ update &(list) => {append(list,entry)} };
  229. export function insert:[T]
  230. &(Reactive[FlexList[T]], {before:FlexListKey}, (FlexListKey,T)) => Sync
  231. &(@list,pos,entry) => @list.{ update &(list) => {insert(list,pos,entry)} };
  232. export function insert:[T]
  233. &(Reactive[FlexList[T]], {after:FlexListKey}, (FlexListKey,T)) => Sync
  234. &(@list,pos,entry) => @list.{ update &(list) => {insert(list,pos,entry)} };
  235. export function move:[T]
  236. &(Reactive[FlexList[T]], FlexListKey, {before:FlexListKey}) => Sync
  237. &(@list,key,pos) => @list.{ update &(list) => {move(list,key,pos)} };
  238. export function move:[T]
  239. &(Reactive[FlexList[T]], FlexListKey, {after:FlexListKey}) => Sync
  240. &(@list,key,pos) => @list.{ update &(list) => {move(list,key,pos)} };
  241. export function move-up:[T]
  242. &(Reactive[FlexList[T]], FlexListKey) => Sync
  243. &(@list,key) => @list.{ update &(list) => {move-up(list,key)} };
  244. export function move-down:[T]
  245. &(Reactive[FlexList[T]], FlexListKey) => Sync
  246. &(@list,key) => @list.{ update &(list) => {move-down(list,key)} };
  247. export function swap:[T]
  248. &(Reactive[FlexList[T]], FlexListKey, FlexListKey) => Sync
  249. &(@list,key1,key2) => @list.{ update &(list) => {swap(list,key1,key2)} };