From 1392e0c477c7b27840f63821fb6cef393c7cb0f4 Mon Sep 17 00:00:00 2001 From: yyc <395976266@qq.com> Date: Sun, 15 Nov 2020 17:49:43 +0800 Subject: [PATCH] perf: ListSt->traverse use iterate instead of recursive --- .../domain_layer/library/structure/ListSt.re | 86 +++++-------------- 1 file changed, 21 insertions(+), 65 deletions(-) diff --git a/src/construct/domain_layer/library/structure/ListSt.re b/src/construct/domain_layer/library/structure/ListSt.re index afd73d726..cc720067a 100755 --- a/src/construct/domain_layer/library/structure/ListSt.re +++ b/src/construct/domain_layer/library/structure/ListSt.re @@ -1,27 +1,6 @@ type t('index, 'value) = list('value); -let rec traverseResultM = (list, f) => { - // define the monadic functions - let (>>=) = (x, f) => Result.bind(x, f); - - let retn = Result.succeed; - - // define a "cons" function - let cons = (head, tail) => [head, ...tail]; - // loop through the list - switch (list) { - | [] => - // if empty, lift [] to a Result - retn([]) - | [head, ...tail] => - // otherwise lift the head to a Result using f - // then lift the tail to a Result using traverse - // then cons the head and tail and return it - f(head) >>= (h => traverseResultM(tail, f) >>= (t => retn(cons(h, t)))) - }; -}; - -let traverseResultMi = (list, f) => { +let traverseResultM = (list, f) => { // define the monadic functions let (>>=) = (x, f) => Result.bind(x, f); @@ -30,40 +9,25 @@ let traverseResultMi = (list, f) => { // define a "cons" function let cons = (head, tail) => [head, ...tail]; - let rec _traverse = (list, i, f) => { - // loop through the list - switch (list) { - | [] => - // if empty, lift [] to a Result - retn([]) - | [head, ...tail] => - // otherwise lift the head to a Result using f - // then lift the tail to a Result using traverse - // then cons the head and tail and return it - f(i, head) - >>= (h => _traverse(tail, i->succ, f) >>= (t => retn(cons(h, t)))) - }; - }; - - _traverse(list, 0, f); + list + ->Belt.List.reduce(retn([]), (newListResult, value) => { + f(value) + >>= (h => newListResult >>= (newList => retn(cons(h, newList)))) + }) + ->Result.mapSuccess(newList => newList->Belt.List.reverse); }; -let rec traverseReduceResultM = - (list: list('a), param: 'b, f: ('b, 'a) => Result.t2('b)) - : Result.t2('b) => { +let traverseReduceResultM = + (list: list('a), param: 'b, f: ('b, 'a) => Result.t2('b)) + : Result.t2('b) => { // define the monadic functions let (>>=) = (x, f) => Result.bind(x, f); let retn = Result.succeed; - // define a "cons" function - let cons = (head, tail) => [head, ...tail]; - // loop through the list - switch (list) { - | [] => retn(param) - | [head, ...tail] => - f(param, head) >>= (h => traverseReduceResultM(tail, h, f)) - }; + list->Belt.List.reduce(retn(param), (paramResult, value) => { + paramResult >>= (param => f(param, value)) + }); }; let traverseReduceResultMi = @@ -74,22 +38,14 @@ let traverseReduceResultMi = let retn = Result.succeed; - // define a "cons" function - let cons = (head, tail) => [head, ...tail]; - - let rec _traverse = (list, param, i, f) => { - // loop through the list - switch (list) { - | [] => retn(param) - | [head, ...tail] => - // otherwise lift the head to a Result using f - // then lift the tail to a Result using traverse - // then cons the head and tail and return it - f(param, (i, head)) >>= (h => _traverse(tail, h, i->succ, f)) - }; - }; - - _traverse(list, param, 0, f); + list->Belt.List.reduce(retn((0, param)), (resultData, value) => { + resultData + >>= ( + ((index, param)) => + f(param, (index, value)) >>= (param => retn((index->succ, param))) + ) + }) + >>= (((_, param)) => retn(param)); }; let _id = value => value;