Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. ---
  2. --- Lua Fun - a high-performance functional programming library for LuaJIT
  3. ---
  4. --- Copyright (c) 2013 Roman Tsisyk <roman@tsisyk.com>
  5. ---
  6. --- Distributed under the MIT/X11 License. See COPYING.md for more details.
  7. ---
  8. --------------------------------------------------------------------------------
  9. -- Tools
  10. --------------------------------------------------------------------------------
  11. local return_if_not_empty = function(state_x, ...)
  12. if state_x == nil then
  13. return nil
  14. end
  15. return ...
  16. end
  17. local call_if_not_empty = function(fun, state_x, ...)
  18. if state_x == nil then
  19. return nil
  20. end
  21. return state_x, fun(...)
  22. end
  23. local function deepcopy(orig) -- used by cycle()
  24. local orig_type = type(orig)
  25. local copy
  26. if orig_type == 'table' then
  27. copy = {}
  28. for orig_key, orig_value in next, orig, nil do
  29. copy[deepcopy(orig_key)] = deepcopy(orig_value)
  30. end
  31. else
  32. copy = orig
  33. end
  34. return copy
  35. end
  36. --------------------------------------------------------------------------------
  37. -- Basic Functions
  38. --------------------------------------------------------------------------------
  39. local nil_gen = function(_param, _state)
  40. return nil
  41. end
  42. local string_gen = function(param, state)
  43. local state = state + 1
  44. if state > #param then
  45. return nil
  46. end
  47. local r = string.sub(param, state, state)
  48. return state, r
  49. end
  50. local pairs_gen = pairs({ a = 0 }) -- get the generating function from pairs
  51. local map_gen = function(tab, key)
  52. local value
  53. local key, value = pairs_gen(tab, key)
  54. return key, key, value
  55. end
  56. local iter = function(obj, param, state)
  57. assert(obj ~= nil, "invalid iterator")
  58. if (type(obj) == "function") then
  59. return obj, param, state
  60. elseif (type(obj) == "table" or type(obj) == "userdata") then
  61. if #obj > 0 then
  62. return ipairs(obj)
  63. else
  64. return map_gen, obj, nil
  65. end
  66. elseif (type(obj) == "string") then
  67. if #obj == 0 then
  68. return nil_gen, nil, nil
  69. end
  70. return string_gen, obj, 0
  71. end
  72. error(string.format('object %s of type "%s" is not iterable',
  73. obj, type(obj)))
  74. end
  75. local iter_tab = function(obj)
  76. if type(obj) == "function" then
  77. return obj, nil, nil
  78. elseif type(obj) == "table" and type(obj[1]) == "function" then
  79. return obj[1], obj[2], obj[3]
  80. else
  81. return iter(obj)
  82. end
  83. end
  84. local each = function(fun, gen, param, state)
  85. local gen_x, param_x, state_x = iter(gen, param, state)
  86. repeat
  87. state_x = call_if_not_empty(fun, gen_x(param_x, state_x))
  88. until state_x == nil
  89. end
  90. --------------------------------------------------------------------------------
  91. -- Generators
  92. --------------------------------------------------------------------------------
  93. local range_gen = function(param, state)
  94. local stop, step = param[1], param[2]
  95. local state = state + step
  96. if state >= stop then
  97. return nil
  98. end
  99. return state, state
  100. end
  101. local range_rev_gen = function(param, state)
  102. local stop, step = param[1], param[2]
  103. local state = state + step
  104. if state <= stop then
  105. return nil
  106. end
  107. return state, state
  108. end
  109. local range = function(start, stop, step)
  110. if step == nil then
  111. step = 1
  112. if stop == nil then
  113. stop = start
  114. start = 0
  115. end
  116. end
  117. assert(type(start) == "number", "start must be a number")
  118. assert(type(stop) == "number", "stop must be a number")
  119. assert(type(step) == "number", "step must be a number")
  120. assert(step ~= 0, "step must not be zero")
  121. if (step > 0) then
  122. return range_gen, {stop, step}, start - step
  123. elseif (step < 0) then
  124. return range_rev_gen, {stop, step}, start - step
  125. end
  126. end
  127. local duplicate_table_gen = function(param_x, state_x)
  128. return state_x + 1, unpack(param_x)
  129. end
  130. local duplicate_fun_gen = function(param_x, state_x)
  131. return state_x + 1, param_x(state_x)
  132. end
  133. local duplicate_gen = function(param_x, state_x)
  134. return state_x + 1, param_x
  135. end
  136. local duplicate = function(...)
  137. if select('#', ...) <= 1 then
  138. return duplicate_gen, select(1, ...), 0
  139. else
  140. return duplicate_table_gen, {...}, 0
  141. end
  142. end
  143. local tabulate = function(fun)
  144. assert(type(fun) == "function")
  145. return duplicate_fun_gen, fun, 0
  146. end
  147. local zeros = function()
  148. return duplicate_gen, 0, 0
  149. end
  150. local ones = function()
  151. return duplicate_gen, 1, 0
  152. end
  153. local rands_gen = function(param_x, _state_x)
  154. return 0, math.random(param_x[1], param_x[2])
  155. end
  156. local rands_nil_gen = function(_param_x, _state_x)
  157. return 0, math.random()
  158. end
  159. local rands = function(n, m)
  160. if n == nil and m == nil then
  161. return rands_nil_gen, 0, 0
  162. end
  163. assert(type(n) == "number", "invalid first arg to rands")
  164. if m == nil then
  165. m = n
  166. n = 0
  167. else
  168. assert(type(m) == "number", "invalid second arg to rands")
  169. end
  170. assert(n < m, "empty interval")
  171. return rands_gen, {n, m - 1}, 0
  172. end
  173. --------------------------------------------------------------------------------
  174. -- Slicing
  175. --------------------------------------------------------------------------------
  176. local nth = function(n, gen, param, state)
  177. assert(n > 0, "invalid first argument to nth")
  178. local gen_x, param_x, state_x = iter(gen, param, state)
  179. -- An optimization for arrays and strings
  180. if gen_x == ipairs then
  181. return param_x[n]
  182. elseif gen_x == string_gen then
  183. if n < #param_x then
  184. return string.sub(param_x, n, n)
  185. else
  186. return nil
  187. end
  188. end
  189. for i=1,n-1,1 do
  190. state_x = gen_x(param_x, state_x)
  191. if state_x == nil then
  192. return nil
  193. end
  194. end
  195. return return_if_not_empty(gen_x(param_x, state_x))
  196. end
  197. local head_call = function(state, ...)
  198. if state == nil then
  199. error("head: iterator is empty")
  200. end
  201. return ...
  202. end
  203. local head = function(gen, param, state)
  204. local gen_x, param_x, state_x = iter(gen, param, state)
  205. return head_call(gen_x(param_x, state_x))
  206. end
  207. local tail = function(gen, param, state)
  208. local gen_x, param_x, state_x = iter(gen, param, state)
  209. state_x = gen_x(param_x, state_x)
  210. if state_x == nil then
  211. return nil_gen, nil, nil
  212. end
  213. return gen_x, param_x, state_x
  214. end
  215. local take_n_gen_x = function(i, state_x, ...)
  216. if state_x == nil then
  217. return nil
  218. end
  219. return {i, state_x}, ...
  220. end
  221. local take_n_gen = function(param, state)
  222. local n, gen_x, param_x = param[1], param[2], param[3]
  223. local i, state_x = state[1], state[2]
  224. if i >= n then
  225. return nil
  226. end
  227. return take_n_gen_x(i + 1, gen_x(param_x, state_x))
  228. end
  229. local take_n = function(n, gen, param, state)
  230. assert(n >= 0, "invalid first argument to take_n")
  231. local gen_x, param_x, state_x = iter(gen, param, state)
  232. return take_n_gen, {n, gen, param}, {0, state}
  233. end
  234. local take_while_gen_x = function(fun, state_x, ...)
  235. if state_x == nil or not fun(...) then
  236. return nil
  237. end
  238. return state_x, ...
  239. end
  240. local take_while_gen = function(param, state_x)
  241. local fun, gen_x, param_x = param[1], param[2], param[3]
  242. return take_while_gen_x(fun, gen_x(param_x, state_x))
  243. end
  244. local take_while = function(fun, gen, param, state)
  245. assert(type(fun) == "function", "invalid first argument to take_while")
  246. local gen_x, param_x, state_x = iter(gen, param, state)
  247. return take_while_gen, {fun, gen, param}, state
  248. end
  249. local take = function(n_or_fun, gen, param, state)
  250. if type(n_or_fun) == "number" then
  251. return take_n(n_or_fun, gen, param, state)
  252. else
  253. return take_while(n_or_fun, gen, param, state)
  254. end
  255. end
  256. local drop_n = function(n, gen, param, state)
  257. assert(n >= 0, "invalid first argument to drop_n")
  258. local gen_x, param_x, state_x = iter(gen, param, state)
  259. for i=1,n,1 do
  260. state_x = gen_x(param_x, state_x)
  261. if state_x == nil then
  262. return nil_gen, nil, nil
  263. end
  264. end
  265. return gen_x, param_x, state_x
  266. end
  267. local drop_while_x = function(fun, state_x, ...)
  268. if state_x == nil or not fun(...) then
  269. return state_x, false
  270. end
  271. return state_x, true, ...
  272. end
  273. local drop_while = function(fun, gen, param, state)
  274. assert(type(fun) == "function", "invalid first argument to drop_while")
  275. local gen_x, param_x, state_x = iter(gen, param, state)
  276. local cont, state_x_prev
  277. repeat
  278. state_x_prev = deepcopy(state_x)
  279. state_x, cont = drop_while_x(fun, gen_x(param_x, state_x))
  280. until not cont
  281. if state_x == nil then
  282. return nil_gen, nil, nil
  283. end
  284. return gen_x, param_x, state_x_prev
  285. end
  286. local drop = function(n_or_fun, gen, param, state)
  287. if type(n_or_fun) == "number" then
  288. return drop_n(n_or_fun, gen, param, state)
  289. else
  290. return drop_while(n_or_fun, gen, param, state)
  291. end
  292. end
  293. local split = function(n_or_fun, gen, param, state)
  294. return {take(n_or_fun, gen, param, state)},
  295. {drop(n_or_fun, gen, param, state)}
  296. end
  297. --------------------------------------------------------------------------------
  298. -- Indexing
  299. --------------------------------------------------------------------------------
  300. local index = function(x, gen, param, state)
  301. local i = 1
  302. for _k, r in iter(gen, param, state) do
  303. if r == x then
  304. return i
  305. end
  306. i = i + 1
  307. end
  308. return nil
  309. end
  310. local indexes_gen = function(param, state)
  311. local x, gen_x, param_x = param[1], param[2], param[3]
  312. local i, state_x = state[1], state[2]
  313. local r
  314. while true do
  315. state_x, r = gen_x(param_x, state_x)
  316. if state_x == nil then
  317. return nil
  318. end
  319. i = i + 1
  320. if r == x then
  321. return {i, state_x}, i
  322. end
  323. end
  324. end
  325. local indexes = function(x, gen, param, state)
  326. local gen_x, param_x, state_x = iter(gen, param, state)
  327. return indexes_gen, {x, gen_x, param_x}, {0, state_x}
  328. end
  329. -- TODO: undocumented
  330. local find = function(fun, gen, param, state)
  331. local gen_x, param_x, state_x = filter(fun, gen, param, state)
  332. return return_if_not_empty(gen_x(param_x, state_x))
  333. end
  334. --------------------------------------------------------------------------------
  335. -- Filtering
  336. --------------------------------------------------------------------------------
  337. local filter1_gen = function(fun, gen_x, param_x, state_x, a)
  338. while true do
  339. if state_x == nil or fun(a) then break; end
  340. state_x, a = gen_x(param_x, state_x)
  341. end
  342. return state_x, a
  343. end
  344. -- call each other
  345. local filterm_gen
  346. local filterm_gen_shrink = function(fun, gen_x, param_x, state_x)
  347. return filterm_gen(fun, gen_x, param_x, gen_x(param_x, state_x))
  348. end
  349. filterm_gen = function(fun, gen_x, param_x, state_x, ...)
  350. if state_x == nil then
  351. return nil
  352. end
  353. if fun(...) then
  354. return state_x, ...
  355. end
  356. return filterm_gen_shrink(fun, gen_x, param_x, state_x)
  357. end
  358. local filter_detect = function(fun, gen_x, param_x, state_x, ...)
  359. if select('#', ...) < 2 then
  360. return filter1_gen(fun, gen_x, param_x, state_x, ...)
  361. else
  362. return filterm_gen(fun, gen_x, param_x, state_x, ...)
  363. end
  364. end
  365. local filter_gen = function(param, state_x)
  366. local fun, gen_x, param_x = param[1], param[2], param[3]
  367. return filter_detect(fun, gen_x, param_x, gen_x(param_x, state_x))
  368. end
  369. local filter = function(fun, gen, param, state)
  370. local gen_x, param_x, state_x = iter(gen, param, state)
  371. return filter_gen, {fun, gen_x, param_x}, state_x
  372. end
  373. local grep = function(fun_or_regexp, gen, param, state)
  374. local fun = fun_or_regexp
  375. if type(fun_or_regexp) == "string" then
  376. fun = function(x) return string.find(x, fun_or_regexp) ~= nil end
  377. end
  378. return filter(fun, gen, param, state)
  379. end
  380. local partition = function(fun, gen, param, state)
  381. local neg_fun = function(...)
  382. return not fun(...)
  383. end
  384. local gen_x, param_x, state_x = iter(gen, param, state)
  385. return {filter(fun, gen_x, param_x, state_x)},
  386. {filter(neg_fun, gen_x, param_x, state_x)}
  387. end
  388. --------------------------------------------------------------------------------
  389. -- Reducing
  390. --------------------------------------------------------------------------------
  391. local foldl_call = function(fun, start, state, ...)
  392. if state == nil then
  393. return nil, start
  394. end
  395. return state, fun(start, ...)
  396. end
  397. local foldl = function(fun, start, gen, param, state)
  398. local gen_x, param_x, state_x = iter(gen, param, state)
  399. while true do
  400. state_x, start = foldl_call(fun, start, gen_x(param_x, state_x))
  401. if state_x == nil then
  402. break;
  403. end
  404. end
  405. return start
  406. end
  407. local length = function(gen, param, state)
  408. local gen, param, state = iter(gen, param, state)
  409. if gen == ipairs or gen == string_gen then
  410. return #param
  411. end
  412. local len = 0
  413. repeat
  414. state = gen(param, state)
  415. len = len + 1
  416. until state == nil
  417. return len - 1
  418. end
  419. local is_null = function(gen, param, state)
  420. local gen_x, param_x, state_x = iter(gen, param, state)
  421. return gen_x(param_x, deepcopy(state_x)) == nil
  422. end
  423. local is_prefix_of = function(iter_x, iter_y)
  424. local gen_x, param_x, state_x = iter_tab(iter_x)
  425. local gen_y, param_y, state_y = iter_tab(iter_y)
  426. local r_x, r_y
  427. for i=1,10,1 do
  428. state_x, r_x = gen_x(param_x, state_x)
  429. state_y, r_y = gen_y(param_y, state_y)
  430. if state_x == nil then
  431. return true
  432. end
  433. if state_y == nil or r_x ~= r_y then
  434. return false
  435. end
  436. end
  437. end
  438. local all = function(fun, gen, param, state)
  439. local gen_x, param_x, state_x = iter(gen, param, state)
  440. local r
  441. repeat
  442. state_x, r = call_if_not_empty(fun, gen_x(param_x, state_x))
  443. until state_x == nil or not r
  444. return state_x == nil
  445. end
  446. local any = function(fun, gen, param, state)
  447. local gen_x, param_x, state_x = iter(gen, param, state)
  448. local r
  449. repeat
  450. state_x, r = call_if_not_empty(fun, gen_x(param_x, state_x))
  451. until state_x == nil or r
  452. return not not r
  453. end
  454. local sum = function(gen, param, state)
  455. local gen, param, state = iter(gen, param, state)
  456. local s = 0
  457. local r = 0
  458. repeat
  459. s = s + r
  460. state, r = gen(param, state)
  461. until state == nil
  462. return s
  463. end
  464. local product = function(gen, param, state)
  465. local gen, param, state = iter(gen, param, state)
  466. local p = 1
  467. local r = 1
  468. repeat
  469. p = p * r
  470. state, r = gen(param, state)
  471. until state == nil
  472. return p
  473. end
  474. local min_cmp = function(m, n)
  475. if n < m then return n else return m end
  476. end
  477. local max_cmp = function(m, n)
  478. if n > m then return n else return m end
  479. end
  480. local min = function(gen, param, state)
  481. local gen, param, state = iter(gen, param, state)
  482. local state, m = gen(param, state)
  483. if state == nil then
  484. error("min: iterator is empty")
  485. end
  486. local cmp
  487. if type(m) == "number" then
  488. -- An optimization: use math.min for numbers
  489. cmp = math.min
  490. else
  491. cmp = min_cmp
  492. end
  493. for _, r in gen, param, state do
  494. m = cmp(m, r)
  495. end
  496. return m
  497. end
  498. local min_by = function(cmp, gen, param, state)
  499. local gen_x, param_x, state_x = iter(gen, param, state)
  500. local state_x, m = gen_x(param_x, state_x)
  501. if state_x == nil then
  502. error("min: iterator is empty")
  503. end
  504. for _, r in gen_x, param_x, state_x do
  505. m = cmp(m, r)
  506. end
  507. return m
  508. end
  509. local max = function(gen, param, state)
  510. local gen_x, param_x, state_x = iter(gen, param, state)
  511. local state_x, m = gen_x(param_x, state_x)
  512. if state_x == nil then
  513. error("max: iterator is empty")
  514. end
  515. local cmp
  516. if type(m) == "number" then
  517. -- An optimization: use math.max for numbers
  518. cmp = math.max
  519. else
  520. cmp = max_cmp
  521. end
  522. for _, r in gen_x, param_x, state_x do
  523. m = cmp(m, r)
  524. end
  525. return m
  526. end
  527. local max_by = function(cmp, gen, param, state)
  528. local gen_x, param_x, state_x = iter(gen, param, state)
  529. local state_x, m = gen_x(param_x, state_x)
  530. if state_x == nil then
  531. error("max: iterator is empty")
  532. end
  533. for _, r in gen_x, param_x, state_x do
  534. m = cmp(m, r)
  535. end
  536. return m
  537. end
  538. local totable = function(gen, param, state)
  539. local gen_x, param_x, state_x = iter(gen, param, state)
  540. local tab, key, val = {}
  541. while true do
  542. state_x, val = gen_x(param_x, state_x)
  543. if state_x == nil then
  544. break
  545. end
  546. table.insert(tab, val)
  547. end
  548. return tab
  549. end
  550. local tomap = function(gen, param, state)
  551. local gen_x, param_x, state_x = iter(gen, param, state)
  552. local tab, key, val = {}
  553. while true do
  554. state_x, key, val = gen_x(param_x, state_x)
  555. if state_x == nil then
  556. break
  557. end
  558. tab[key] = val
  559. end
  560. return tab
  561. end
  562. --------------------------------------------------------------------------------
  563. -- Transformations
  564. --------------------------------------------------------------------------------
  565. local map_gen = function(param, state)
  566. local gen_x, param_x, fun = param[1], param[2], param[3]
  567. return call_if_not_empty(fun, gen_x(param_x, state))
  568. end
  569. local map = function(fun, gen, param, state)
  570. local gen_x, param_x, state_x = iter(gen, param, state)
  571. return map_gen, {gen_x, param_x, fun}, state_x
  572. end
  573. local enumerate_gen_call = function(state, i, state_x, ...)
  574. if state_x == nil then
  575. return nil
  576. end
  577. return {i + 1, state_x}, i, ...
  578. end
  579. local enumerate_gen = function(param, state)
  580. local gen_x, param_x = param[1], param[2]
  581. local i, state_x = state[1], state[2]
  582. return enumerate_gen_call(state, i, gen_x(param_x, state_x))
  583. end
  584. local enumerate = function(gen, param, state)
  585. local gen_x, param_x, state_x = iter(gen, param, state)
  586. return enumerate_gen, {gen_x, param_x}, {0, state_x}
  587. end
  588. local intersperse_call = function(i, state_x, ...)
  589. if state_x == nil then
  590. return nil
  591. end
  592. return {i + 1, state_x}, ...
  593. end
  594. local intersperse_gen = function(param, state)
  595. local x, gen_x, param_x = param[1], param[2], param[3]
  596. local i, state_x = state[1], state[2]
  597. if i % 2 == 1 then
  598. return {i + 1, state_x}, x
  599. else
  600. return intersperse_call(i, gen_x(param_x, state_x))
  601. end
  602. end
  603. -- TODO: interperse must not add x to the tail
  604. local intersperse = function(x, gen, param, state)
  605. local gen_x, param_x, state_x = iter(gen, param, state)
  606. return intersperse_gen, {x, gen_x, param_x}, {0, state_x}
  607. end
  608. --------------------------------------------------------------------------------
  609. -- Compositions
  610. --------------------------------------------------------------------------------
  611. local function zip_gen_r(param, state, state_new, ...)
  612. if #state_new == #param / 2 then
  613. return state_new, ...
  614. end
  615. local i = #state_new + 1
  616. local gen_x, param_x = param[2 * i - 1], param[2 * i]
  617. local state_x, r = gen_x(param_x, state[i])
  618. -- print('i', i, 'state_x', state_x, 'r', r)
  619. if state_x == nil then
  620. return nil
  621. end
  622. table.insert(state_new, state_x)
  623. return zip_gen_r(param, state, state_new, r, ...)
  624. end
  625. local zip_gen = function(param, state)
  626. return zip_gen_r(param, state, {})
  627. end
  628. local zip = function(...)
  629. local n = select('#', ...)
  630. if n == 0 then
  631. return nil_gen, nil, nil
  632. end
  633. local param = { [2 * n] = 0 }
  634. local state = { [n] = 0 }
  635. local i, gen_x, param_x, state_x
  636. for i=1,n,1 do
  637. local elem = select(n - i + 1, ...)
  638. gen_x, param_x, state_x = iter_tab(elem)
  639. param[2 * i - 1] = gen_x
  640. param[2 * i] = param_x
  641. state[i] = state_x
  642. end
  643. return zip_gen, param, state
  644. end
  645. local cycle_gen_call = function(param, state_x, ...)
  646. if state_x == nil then
  647. local gen_x, param_x, state_x0 = param[1], param[2], param[3]
  648. return gen_x(param_x, deepcopy(state_x0))
  649. end
  650. return state_x, ...
  651. end
  652. local cycle_gen = function(param, state_x)
  653. local gen_x, param_x, state_x0 = param[1], param[2], param[3]
  654. return cycle_gen_call(param, gen_x(param_x, state_x))
  655. end
  656. local cycle = function(gen, param, state)
  657. local gen_x, param_x, state_x = iter(gen, param, state)
  658. return cycle_gen, {gen_x, param_x, state_x}, deepcopy(state_x)
  659. end
  660. -- call each other
  661. local chain_gen_r1
  662. local chain_gen_r2 = function(param, state, state_x, ...)
  663. if state_x == nil then
  664. local i = state[1]
  665. i = i + 1
  666. if i > #param / 3 then
  667. return nil
  668. end
  669. local state_x = param[3 * i]
  670. return chain_gen_r1(param, {i, state_x})
  671. end
  672. return {state[1], state_x}, ...
  673. end
  674. chain_gen_r1 = function(param, state)
  675. local i, state_x = state[1], state[2]
  676. local gen_x, param_x = param[3 * i - 2], param[3 * i - 1]
  677. return chain_gen_r2(param, state, gen_x(param_x, state[2]))
  678. end
  679. local chain = function(...)
  680. local n = select('#', ...)
  681. if n == 0 then
  682. return nil_gen, nil, nil
  683. end
  684. local param = { [3 * n] = 0 }
  685. local i, gen_x, param_x, state_x
  686. for i=1,n,1 do
  687. local elem = select(i, ...)
  688. gen_x, param_x, state_x = iter_tab(elem)
  689. param[3 * i - 2] = gen_x
  690. param[3 * i - 1] = param_x
  691. param[3 * i] = state_x
  692. end
  693. return chain_gen_r1, param, {1, param[3]}
  694. end
  695. --------------------------------------------------------------------------------
  696. -- Operators
  697. --------------------------------------------------------------------------------
  698. operator = {
  699. ----------------------------------------------------------------------------
  700. -- Comparison operators
  701. ----------------------------------------------------------------------------
  702. lt = function(a, b) return a < b end,
  703. le = function(a, b) return a <= b end,
  704. eq = function(a, b) return a == b end,
  705. ne = function(a, b) return a ~= b end,
  706. ge = function(a, b) return a >= b end,
  707. gt = function(a, b) return a > b end,
  708. ----------------------------------------------------------------------------
  709. -- Arithmetic operators
  710. ----------------------------------------------------------------------------
  711. add = function(a, b) return a + b end,
  712. div = function(a, b) return a / b end,
  713. floordiv = function(a, b) return math.floor(a/b) end,
  714. intdiv = function(a, b)
  715. local q = a / b
  716. if a >= 0 then return math.floor(q) else return math.ceil(q) end
  717. end,
  718. mod = function(a, b) return a % b end,
  719. mul = function(a, b) return a * b end,
  720. neq = function(a) return -a end,
  721. unm = function(a) return -a end, -- an alias
  722. pow = function(a, b) return a ^ b end,
  723. sub = function(a, b) return a - b end,
  724. truediv = function(a, b) return a / b end,
  725. ----------------------------------------------------------------------------
  726. -- String operators
  727. ----------------------------------------------------------------------------
  728. concat = function(a, b) return a..b end,
  729. len = function(a) return #a end,
  730. length = function(a) return #a end, -- an alias
  731. ----------------------------------------------------------------------------
  732. -- Logical operators
  733. ----------------------------------------------------------------------------
  734. land = function(a, b) return a and b end,
  735. lor = function(a, b) return a or b end,
  736. lnot = function(a) return not a end,
  737. truth = function(a) return not not a end,
  738. }
  739. --------------------------------------------------------------------------------
  740. -- module definitions
  741. --------------------------------------------------------------------------------
  742. local exports = {
  743. ----------------------------------------------------------------------------
  744. -- Basic
  745. ----------------------------------------------------------------------------
  746. iter = iter,
  747. each = each,
  748. for_each = each, -- an alias
  749. foreach = each, -- an alias
  750. ----------------------------------------------------------------------------
  751. -- Generators
  752. ----------------------------------------------------------------------------
  753. range = range,
  754. duplicate = duplicate,
  755. xrepeat = duplicate, -- an alias
  756. replicate = duplicate, -- an alias
  757. tabulate = tabulate,
  758. ones = ones,
  759. zeros = zeros,
  760. rands = rands,
  761. ----------------------------------------------------------------------------
  762. -- Slicing
  763. ----------------------------------------------------------------------------
  764. nth = nth,
  765. head = head,
  766. car = head, -- an alias
  767. tail = tail,
  768. cdr = tail, -- an alias
  769. take_n = take_n,
  770. take_while = take_while,
  771. take = take,
  772. drop_n = drop_n,
  773. drop_while = drop_while,
  774. drop = drop,
  775. split = split,
  776. split_at = split, -- an alias
  777. span = split, -- an alias
  778. ----------------------------------------------------------------------------
  779. -- Indexing
  780. ----------------------------------------------------------------------------
  781. index = index,
  782. index_of = index, -- an alias
  783. elem_index = index, -- an alias
  784. indexes = indexes,
  785. indices = indexes, -- an alias
  786. elem_indexes = indexes, -- an alias
  787. elem_indices = indexes, -- an alias
  788. find = find,
  789. ----------------------------------------------------------------------------
  790. -- Filtering
  791. ----------------------------------------------------------------------------
  792. filter = filter,
  793. remove_if = filter, -- an alias
  794. grep = grep,
  795. partition = partition,
  796. ----------------------------------------------------------------------------
  797. -- Reducing
  798. ----------------------------------------------------------------------------
  799. foldl = foldl,
  800. reduce = foldl, -- an alias
  801. length = length,
  802. is_null = is_null,
  803. is_prefix_of = is_prefix_of,
  804. all = all,
  805. every = all, -- an alias
  806. any = any,
  807. some = any, -- an alias
  808. sum = sum,
  809. product = product,
  810. min = min,
  811. minimum = min, -- an alias
  812. min_by = min_by,
  813. minimum_by = min_by, -- an alias
  814. max = max,
  815. maximum = max, -- an alias
  816. max_by = max_by,
  817. maximum_by = max_by, -- an alias
  818. totable = totable,
  819. tomap = tomap,
  820. ----------------------------------------------------------------------------
  821. -- Transformations
  822. ----------------------------------------------------------------------------
  823. map = map,
  824. enumerate = enumerate,
  825. intersperse = intersperse,
  826. ----------------------------------------------------------------------------
  827. -- Compositions
  828. ----------------------------------------------------------------------------
  829. zip = zip,
  830. cycle = cycle,
  831. chain = chain,
  832. ----------------------------------------------------------------------------
  833. -- Operators
  834. ----------------------------------------------------------------------------
  835. operator = operator,
  836. op = operator -- an alias
  837. }
  838. -- a special syntax sugar to export all functions to the global table
  839. setmetatable(exports, {
  840. __call = function(t)
  841. for k, v in pairs(t) do _G[k] = v end
  842. end,
  843. })
  844. return exports