Skip to content

Commit

Permalink
perf: ListSt->traverse use iterate instead of recursive
Browse files Browse the repository at this point in the history
  • Loading branch information
yyc-git committed Nov 15, 2020
1 parent 6b40e53 commit 1392e0c
Showing 1 changed file with 21 additions and 65 deletions.
86 changes: 21 additions & 65 deletions src/construct/domain_layer/library/structure/ListSt.re
Original file line number Diff line number Diff line change
@@ -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);

Expand All @@ -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 =
Expand All @@ -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;
Expand Down

0 comments on commit 1392e0c

Please sign in to comment.