From 6607e57ec84b7779894267a962f7c5c86ba1e534 Mon Sep 17 00:00:00 2001 From: Renegatto Date: Sat, 25 Oct 2025 12:08:48 +0300 Subject: [PATCH 1/2] Use correct Semigroup.append instead table.concat --- src/Data/Traversable.lua | 39 ++++++++++++++++++++------------------- src/Data/Traversable.purs | 3 ++- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/Data/Traversable.lua b/src/Data/Traversable.lua index a846178..931fd5b 100644 --- a/src/Data/Traversable.lua +++ b/src/Data/Traversable.lua @@ -1,31 +1,32 @@ local array1 = function(a) return {a} end local array2 = function(a) return function(b) return {a, b} end end local array3 = function(a) return function(b) return function(c) return {a, b, c} end end end -local concat2 = function(xs) return function(ys) return table.concat(xs, ys) end end return { traverseArrayImpl = (function(apply) return function(map) return function(pure) - return function(f) - return function(array) - local function go(bot, top) - if top - bot == 0 then - return pure({}) - elseif top - bot == 1 then - return map(array1)(f(array[bot])) - elseif top - bot == 2 then - return apply(map(array2)(f(array[bot])))(f(array[bot + 1])) - elseif top - bot == 3 then - return apply(apply(map(array3)(f(array[bot])))(f(array[bot + 1])))(f(array[bot + 2])) - else - -- This slightly tricky pivot selection aims to produce two - -- even-length partitions where possible. - local pivot = bot + math.floor((top - bot) / 4) * 2 - return apply(map(concat2)(go(bot, pivot)))(go(pivot, top)) + return function (appendArrays) + return function(f) + return function(array) + local function go(bot, top) + if top - bot == 0 then + return pure({}) + elseif top - bot == 1 then + return map(array1)(f(array[bot])) + elseif top - bot == 2 then + return apply(map(array2)(f(array[bot])))(f(array[bot + 1])) + elseif top - bot == 3 then + return apply(apply(map(array3)(f(array[bot])))(f(array[bot + 1])))(f(array[bot + 2])) + else + -- This slightly tricky pivot selection aims to produce two + -- even-length partitions where possible. + local pivot = bot + math.floor((top - bot) / 4) * 2 + return apply(map(appendArrays)(go(bot, pivot)))(go(pivot, top)) + end end - end - return go(0, #array) + return go(0, #array) + end end end end diff --git a/src/Data/Traversable.purs b/src/Data/Traversable.purs index 180bf2f..c8342b0 100644 --- a/src/Data/Traversable.purs +++ b/src/Data/Traversable.purs @@ -100,7 +100,7 @@ sequenceDefault sequenceDefault = traverse identity instance traversableArray :: Traversable Array where - traverse = traverseArrayImpl apply map pure + traverse = traverseArrayImpl apply map pure (<>) sequence = sequenceDefault foreign import traverseArrayImpl @@ -108,6 +108,7 @@ foreign import traverseArrayImpl . (forall x y. m (x -> y) -> m x -> m y) -> (forall x y. (x -> y) -> m x -> m y) -> (forall x. x -> m x) + -> (forall x. Array x -> Array x -> Array x) -> (a -> m b) -> Array a -> m (Array b) From c129cb59954f65dd03ec40759312ae8574e699ee Mon Sep 17 00:00:00 2001 From: Renegatto <46404781+Renegatto@users.noreply.github.com> Date: Sat, 25 Oct 2025 13:28:28 +0300 Subject: [PATCH 2/2] Fix: consider array indexing starting from 1 in lua Traverse used JS implementation which is OK except that the array indexing was starting from 0. --- src/Data/Traversable.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Data/Traversable.lua b/src/Data/Traversable.lua index 931fd5b..2592d76 100644 --- a/src/Data/Traversable.lua +++ b/src/Data/Traversable.lua @@ -12,11 +12,11 @@ return { if top - bot == 0 then return pure({}) elseif top - bot == 1 then - return map(array1)(f(array[bot])) + return map(array1)(f(array[bot + 1])) elseif top - bot == 2 then - return apply(map(array2)(f(array[bot])))(f(array[bot + 1])) + return apply(map(array2)(f(array[bot + 1])))(f(array[bot + 2])) elseif top - bot == 3 then - return apply(apply(map(array3)(f(array[bot])))(f(array[bot + 1])))(f(array[bot + 2])) + return apply(apply(map(array3)(f(array[bot + 1])))(f(array[bot + 2])))(f(array[bot + 3])) else -- This slightly tricky pivot selection aims to produce two -- even-length partitions where possible.