diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e5af83..5f2f4d42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Breaking changes: New features: Bugfixes: +- Avoid `RangeError` in `arrayBind` foreign implementation (#314 by @pete-murphy) Other improvements: diff --git a/src/Control/Bind.js b/src/Control/Bind.js index fa0dbaeb..bf79719f 100644 --- a/src/Control/Bind.js +++ b/src/Control/Bind.js @@ -1,9 +1,21 @@ -export const arrayBind = function (arr) { - return function (f) { - var result = []; - for (var i = 0, l = arr.length; i < l; i++) { - Array.prototype.push.apply(result, f(arr[i])); +export const arrayBind = + typeof Array.prototype.flatMap === "function" + ? function (arr) { + return function (f) { + return arr.flatMap(f); + }; } - return result; - }; -}; + : function (arr) { + return function (f) { + var result = []; + var l = arr.length; + for (var i = 0; i < l; i++) { + var xs = f(arr[i]); + var k = xs.length; + for (var j = 0; j < k; j++) { + result.push(xs[j]); + } + } + return result; + }; + }; diff --git a/test/Test/Main.js b/test/Test/Main.js index b25cdaca..72ebcd92 100644 --- a/test/Test/Main.js +++ b/test/Test/Main.js @@ -40,3 +40,11 @@ export function testNumberShow(showNumber) { ]); }; } + +export function makeArray(length) { + var arr = []; + for (var i = 0; i < length; i++) { + arr.push(i); + } + return arr; +} diff --git a/test/Test/Main.purs b/test/Test/Main.purs index 13ea2cce..fd763cf0 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -22,6 +22,7 @@ main = do testReflectType testReifyType testSignum + testArrayBind foreign import testNumberShow :: (Number -> String) -> AlmostEff @@ -189,3 +190,14 @@ testSignum = do assert "signum positive zero" $ show (1.0/(signum 0.0)) == "Infinity" assert "Clarifies what 'signum negative zero' test is doing" $ show (1.0/(-0.0)) == "-Infinity" assert "signum negative zero" $ show (1.0/(signum (-0.0))) == "-Infinity" + +foreign import makeArray :: Int -> Array Int + +testArrayBind :: AlmostEff +testArrayBind = do + assert "Array bind does not cause RangeError" do + let + _ = do + _ <- [unit] + makeArray 106_000 + true