Skip to content

Commit 65a826d

Browse files
committed
make function composition stack safe
1 parent 8bf3ca6 commit 65a826d

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
},
88
"devDependencies": {
99
"eslint": "^3.17.1",
10-
"purescript-psa": "^0.5.0-rc.1",
11-
"pulp": "^10.0.4",
10+
"purescript-psa": "^0.5.1",
11+
"pulp": "^11.0.0",
1212
"rimraf": "^2.6.1"
1313
}
1414
}

src/Control/Semigroupoid.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use strict";
2+
3+
// https://medium.com/@safareli/stack-safe-function-composition-85d61feee37e
4+
var runComposition = function(composition, x) {
5+
var root = composition;
6+
var val = x;
7+
var stack = [];
8+
for (;;) {
9+
if (root._0 !== undefined){
10+
stack.push(root._1);
11+
root = root._0;
12+
} else {
13+
val = root(val);
14+
if (stack.length === 0) {
15+
return val;
16+
}
17+
root = stack.shift();
18+
}
19+
}
20+
};
21+
22+
exports.functionCompose = function(f) {
23+
return function(g) {
24+
var res = function composition(x) {
25+
return runComposition(composition, x);
26+
};
27+
res._0 = g;
28+
res._1 = f;
29+
return res;
30+
};
31+
};

src/Control/Semigroupoid.purs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ class Semigroupoid a where
1313
compose :: forall b c d. a c d -> a b c -> a b d
1414

1515
instance semigroupoidFn :: Semigroupoid (->) where
16-
compose f g x = f (g x)
16+
compose = functionCompose
17+
18+
foreign import functionCompose :: forall b c d. (c -> d) -> (b -> c) -> (b -> d)
1719

1820
infixr 9 compose as <<<
1921

test/Test/Main.purs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,21 @@ type AlmostEff = Unit -> Unit
66

77
main :: AlmostEff
88
main = do
9+
functionComposition
910
testNumberShow show
1011
testOrderings
1112
testOrdUtils
1213
testIntDegree
1314

15+
functionComposition :: AlmostEff
16+
functionComposition =
17+
assert
18+
("composition is stack safe")
19+
(composeGo (_ + 1) id 0 0 == 100000)
20+
21+
composeGo :: forall x a. Semigroupoid x => x a a -> x a a -> Int -> x a a
22+
composeGo f acc n = if n == 100000 then acc else composeGo f (compose acc f) (n + 1)
23+
1424
foreign import testNumberShow :: (Number -> String) -> AlmostEff
1525
foreign import throwErr :: String -> AlmostEff
1626

0 commit comments

Comments
 (0)