From 9da225a93f7c5aaf52665f390d536e8a0e80e48a Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Fri, 10 Jul 2026 13:28:31 +0200 Subject: [PATCH 1/6] feat: lift the *.Uncurried run wrappers to direct n-ary calls (#198) Lift runFn2-10, runSTFn1-10, runEffectFn1-10 from their curried runtime fallbacks into inline-always IR through the foreign lifter (#178) and the AppN node (#179): runFn3 becomes `\fn a b c -> AppN fn [a, b, c]` and runSTFn2 becomes `\fn a b -> Abs _ (AppN fn [a, b])`. A saturated call site beta-reduces to a single n-ary Lua call; a partial application keeps the curried fallback. The mk* wrappers need an n-ary AbsN (#24) and stay opaque. An Effect/ST statement whose action is such a lifted wrapper sheds its last closure at codegen: the effect run of a literal thunk `(\_ -> fn(a...)) EffectRunArg` lowers straight to `fn(a...)` rather than `(function() return fn(a...) end)()`. The EffectRunArg marker stays in the IR so DCE still keeps the result-unused effect statement; only the Lua backend drops the redundant force. --- ...0_131814_unisay_lift_uncurried_wrappers.md | 21 ++ lib/Language/PureScript/Backend/Lua.hs | 16 ++ .../PureScript/Backend/Lua/ForeignLift.hs | 60 ++++- .../Backend/Lua/ForeignLift/Spec.hs | 96 ++++++- .../Golden.StringCodePoints.Test/golden.ir | 220 +++++++-------- .../Golden.StringCodePoints.Test/golden.lua | 190 ++++++------- .../Golden.UncurriedLift.Test/corefn.json | 1 + .../Golden.UncurriedLift.Test/eval/.gitignore | 1 + .../Golden.UncurriedLift.Test/eval/golden.txt | 6 + .../Golden.UncurriedLift.Test/golden.ir | 250 ++++++++++++++++++ .../Golden.UncurriedLift.Test/golden.lua | 38 +++ test/ps/spago.lock | 1 + test/ps/spago.yaml | 1 + test/ps/src/Golden/UncurriedLift/Test.purs | 45 ++++ 14 files changed, 732 insertions(+), 214 deletions(-) create mode 100644 changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md create mode 100644 test/ps/output/Golden.UncurriedLift.Test/corefn.json create mode 100644 test/ps/output/Golden.UncurriedLift.Test/eval/.gitignore create mode 100644 test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt create mode 100644 test/ps/output/Golden.UncurriedLift.Test/golden.ir create mode 100644 test/ps/output/Golden.UncurriedLift.Test/golden.lua create mode 100644 test/ps/src/Golden/UncurriedLift/Test.purs diff --git a/changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md b/changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md new file mode 100644 index 00000000..13dd341a --- /dev/null +++ b/changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md @@ -0,0 +1,21 @@ +### Changed + +- The `run` half of the `*.Uncurried` FFI wrappers now lifts to direct n-ary + calls (#198). Building on the foreign lifter (#178) and the `AppN` node + (#179), `runFn2`…`runFn10`, `runSTFn1`…`runSTFn10`, and + `runEffectFn1`…`runEffectFn10` are lifted from their curried runtime + fallbacks to inline-always IR: `runFn3` becomes `\fn a b c -> AppN fn [a, b, + c]`, and `runSTFn2` becomes `\fn a b -> Abs _ (AppN fn [a, b])` (the trailing + effect thunk is a unary lambda with an unused parameter). A saturated call + site then beta-reduces to a single n-ary Lua call, so `runFn3 impl x y z` + compiles to `impl(x, y, z)` rather than the two-closure curried onion; a + partial application keeps the wrapper's curried fallback. The `mk` + counterparts need an n-ary `AbsN` (#24) and stay opaque. +- An `Effect`/`ST` statement whose action is a lifted uncurried wrapper now + sheds its final closure at code generation: the effect run of a literal thunk, + `(\_ -> fn(a, …)) EffectRunArg`, lowers straight to the call `fn(a, …)` + instead of `(function() return fn(a, …) end)()`. The `EffectRunArg` marker is + kept through the IR pipeline so dead-code elimination still keeps the + result-unused effect statement; only the Lua backend drops the redundant + force. On the ST/Array boundary this turns `runSTFn2(pushImpl)(x)(arr)()` from + four calls and three closures into one `pushImpl(x, arr)`. diff --git a/lib/Language/PureScript/Backend/Lua.hs b/lib/Language/PureScript/Backend/Lua.hs index f5410426..9d72daa9 100644 --- a/lib/Language/PureScript/Backend/Lua.hs +++ b/lib/Language/PureScript/Backend/Lua.hs @@ -239,6 +239,22 @@ fromIR foreigns topLevelNames modname ir = case ir of pure . Right $ case body of Left chunk → Lua.functionDef luaParams chunk Right e → Lua.functionDef luaParams [Lua.return e] + -- Running the literal thunk a saturated lifted @*.Uncurried@ effect wrapper + -- reduces to — @(\_ -> fn(a, …)) EffectRunArg@ — is just the call + -- @fn(a, …)@: the uncurried @fn@ runs once it has every argument, so no + -- thunk need be built and immediately forced (issue #198). This is the + -- effect-side payoff of the lift — @fn(a, …)@ instead of + -- @(function() return fn(a, …) end)()@. The 'IR.EffectRunArg' marker is + -- kept in the IR through the pipeline, so dead-code elimination still keeps + -- the (result-unused) effect statement (see 'IR.isEffectRun'); only codegen + -- drops the redundant force. The body is required to be an 'IR.AppN', which + -- always lowers to an expression — so this never inlines a 'Let' (magic-do + -- keeps such chunk boundaries thunked to bound locals per Lua function). + IR.AppN + _ann + (IR.AbsN _ (IR.ParamUnused _ :| []) body@IR.AppN {}) + (IR.EffectRunArg _ :| []) → + Right <$> goExp body IR.AppN _ann fn args → do e ← goExp fn -- See Note [Nullary functions and Prim.undefined]. PS inserts a diff --git a/lib/Language/PureScript/Backend/Lua/ForeignLift.hs b/lib/Language/PureScript/Backend/Lua/ForeignLift.hs index fe7be18e..baea0cd1 100644 --- a/lib/Language/PureScript/Backend/Lua/ForeignLift.hs +++ b/lib/Language/PureScript/Backend/Lua/ForeignLift.hs @@ -22,12 +22,27 @@ registry of qualified-name → IR mappings, is what makes registry drift against the package set impossible by construction — the payoff of Lua's tiny grammar (issue #178). +The same machinery lifts the @run@ half of the @*.Uncurried@ wrappers +(issue #198): @runFn3@ becomes @\\fn a b c -> AppN fn [a, b, c]@ and +@runSTFn2@ becomes @\\fn a b -> Abs _ (AppN fn [a, b])@ (the trailing +effect thunk is a unary lambda with an unused parameter). Marked +inline-always like every lifted accessor, a saturated call site collapses +to a single n-ary Lua call after beta reduction, and the effect thunk then +fuses away in statement position via magicDo — turning +@runSTFn2(pushImpl)(x)(arr)()@ from four calls and three closures into one +@pushImpl(x, arr)@. + = What lifts The translatable subset, mirroring the shapes the prelude forks actually use: * curried single-parameter function literals → nested 'Abs'; + * a zero-parameter function literal (the @*.Uncurried@ effect thunk, + @function() … end@) → a unary 'Abs' with an unused parameter; + * a saturated call @fn(a, b, …)@ of one or more arguments → the n-ary + 'AppN' node (issue #198); a nullary @fn()@ has no 'AppN' and does not + lift; * @return@ / @if … then … else@ trees (an @elseif@ is a nested @if@ in the else branch) → 'IfThenElse', provided every branch returns a value (a branch that falls through to @nil@ does not lift); @@ -38,9 +53,9 @@ use: header (inlined) — this is how @ordIntImpl = (unsafeCoerceImpl)@ and the @refEq@ aliases resolve. -Everything else — loops, mutation, varargs, table constructors, calls, -multi-parameter functions, string/char literals — leaves the export -opaque (correct for e.g. @foldlArray@). +Everything else — loops, mutation, varargs, table constructors, +multi-parameter function literals, string/char literals — leaves the +export opaque (correct for e.g. @foldlArray@). -} module Language.PureScript.Backend.Lua.ForeignLift ( liftForeigns @@ -69,12 +84,14 @@ import Language.PureScript.Backend.IR.Types , PrimOp (..) , RawExp (ForeignImport, ObjectProp) , abstraction + , applicationN , eq , ifThenElse , literalBool , literalFloat , literalInt , paramNamed + , paramUnused , primBinOp , primNot , refLocal @@ -101,11 +118,11 @@ import Prelude hiding (show) -------------------------------------------------------------------------------- -- Allowlist ------------------------------------------------------------------- -{- | The foreign exports lifted into the IR — the arithmetic, comparison, -boolean, and concatenation core of the prelude (issue #178). Membership -is a hard contract (see the module header): a listed export that fails to -lift is a compile error. The @*.Uncurried@ modules and a broader -allowlist are follow-up work (issues #179, #187). +{- | The foreign exports lifted into the IR: the arithmetic, comparison, +boolean, and concatenation core of the prelude (issue #178), plus the +@run@ half of the @*.Uncurried@ wrappers (issue #198). Membership is a +hard contract (see the module header): a listed export that fails to lift +is a compile error. A broader allowlist is follow-up work (issue #187). -} allowlist ∷ Set QName allowlist = @@ -133,8 +150,20 @@ allowlist = ] ) , ("Data.Semigroup", ["concatString"]) + , -- The @run@ half of the uncurried FFI wrappers (issue #198). Their + -- @mk@ counterparts need an n-ary 'AbsN' (issue #24) and stay opaque; + -- @runFn0@ is a nullary call with no 'AppN', @runFn1@ is PureScript + -- @id@ with no foreign — both absent below. + ("Data.Function.Uncurried", runWrappers "runFn" [2 .. 10]) + , ("Control.Monad.ST.Uncurried", runWrappers "runSTFn" [1 .. 10]) + , ("Effect.Uncurried", runWrappers "runEffectFn" [1 .. 10]) ] + -- @[prefix | n <- arities]@, e.g. @runWrappers "runFn" [2, 3]@ is + -- @["runFn2", "runFn3"]@. + runWrappers ∷ Text → [Int] → [Text] + runWrappers prefix arities = [prefix <> toText (show n) | n ← arities] + -------------------------------------------------------------------------------- -- Orchestration --------------------------------------------------------------- @@ -275,6 +304,21 @@ liftLuaExp env bound = \case Function [(_ann, ParamNamed param)] body → abstraction (paramNamed (irName param)) <$> liftBlock env (Set.insert param bound) body + -- A zero-parameter function literal is the effect thunk of the + -- @run{ST,Effect}FnN@ wrappers: @function() return fn(a, b) end@. It + -- lifts to a unary 'Abs' with an unused parameter — the shape magicDo + -- executes in statement position, so a saturated site fuses the thunk + -- away entirely (issue #198). + Function [] body → + abstraction paramUnused <$> liftBlock env bound body + -- A saturated call @fn(a, b, …)@ — the body of the @runFnN@ wrappers — + -- lifts to the n-ary 'AppN' node (issue #198). A nullary call @fn()@ + -- has no 'AppN' representation, so 'nonEmpty' declines it (e.g. + -- @runFn0 = \\fn -> fn()@ stays opaque). + FunctionCall (_ann, fn) args → do + fn' ← liftLuaExp env bound fn + args' ← nonEmpty args >>= traverse (\(_ann', a) → liftLuaExp env bound a) + Just (applicationN fn' args') _ → Nothing {- | Translate a block that must be a pure return tree: a single @return@ diff --git a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs index 22452275..c725af57 100644 --- a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs +++ b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs @@ -9,9 +9,11 @@ import Language.PureScript.Backend.IR.Names import Language.PureScript.Backend.IR.Types ( PrimOp (..) , abstraction + , applicationN , eq , ifThenElse , paramNamed + , paramUnused , primBinOp , primNot , refLocal @@ -98,11 +100,90 @@ spec = describe "Foreign lift (#178)" do primBinOp PrimConcat (refLocal (Name "s1")) (refLocal (Name "s2")) ) + describe "lifts the *.Uncurried run wrappers (#198)" do + it "lifts runFn3 to a saturated n-ary call" do + -- The pure wrapper: `\fn a b c -> fn(a, b, c)`. The body is a single + -- Lua call of every parameter at once, which lifts to the n-ary AppN + -- node. Marked inline-always downstream, a saturated site beta-reduces + -- to a direct `AppN impl [x, y, z]`. + let src = + "return { runFn3 = function(fn) return function(a) " + <> "return function(b) return function(c) " + <> "return fn(a, b, c) end end end end }" + fn = Name "fn" + a = Name "a" + b = Name "b" + c = Name "c" + liftExport (source src) (Name "runFn3") + `shouldBe` Just + ( abstraction (paramNamed fn) $ + abstraction (paramNamed a) $ + abstraction (paramNamed b) $ + abstraction (paramNamed c) $ + applicationN + (refLocal fn) + (refLocal a :| [refLocal b, refLocal c]) + ) + + it "lifts runSTFn2 to a thunk over an n-ary call" do + -- The effectful wrapper: `\fn a b -> \() -> fn(a, b)`. The trailing + -- `function()` thunk becomes a unary lambda with an unused parameter + -- (Abs paramUnused) — the exact shape magicDo already executes in + -- statement position, so the thunk and its three closures fuse away. + let src = + "return { runSTFn2 = function(fn) return function(a) " + <> "return function(b) return function() " + <> "return fn(a, b) end end end end }" + fn = Name "fn" + a = Name "a" + b = Name "b" + liftExport (source src) (Name "runSTFn2") + `shouldBe` Just + ( abstraction (paramNamed fn) $ + abstraction (paramNamed a) $ + abstraction (paramNamed b) $ + abstraction paramUnused $ + applicationN (refLocal fn) (refLocal a :| [refLocal b]) + ) + + it "lifts runEffectFn1 (single-argument n-ary call under a thunk)" do + let src = + "return { runEffectFn1 = function(fn) return function(a) " + <> "return function() return fn(a) end end end }" + fn = Name "fn" + a = Name "a" + liftExport (source src) (Name "runEffectFn1") + `shouldBe` Just + ( abstraction (paramNamed fn) $ + abstraction (paramNamed a) $ + abstraction paramUnused $ + applicationN (refLocal fn) (refLocal a :| []) + ) + + it "declines the mk* wrappers (their inner function is n-ary, #24)" do + -- `mkFn2 = \fn -> function(a, b) return fn(a)(b) end`: the inner + -- multi-parameter function needs an n-ary AbsN (issue #24), so the + -- wrapper stays an opaque foreign, not on this allowlist. + liftExport + ( source + "return { mkFn2 = function(fn) return function(a, b) return fn(a)(b) end end }" + ) + (Name "mkFn2") + `shouldSatisfy` isNothing + describe "declines everything outside the subset" do it "declines a multi-parameter function (would misapply when curried)" do liftExport (source "return { f = function(x, y) return x + y end }") (Name "f") `shouldSatisfy` isNothing + it "declines a nullary call (AppN cannot express a zero-argument call)" do + -- `runFn0 = \fn -> fn()`. An n-ary AppN needs at least one argument; + -- the zero-argument call falls outside the subset and stays opaque. + liftExport + (source "return { runFn0 = function(fn) return fn() end }") + (Name "runFn0") + `shouldSatisfy` isNothing + it "declines a body with a table index" do liftExport (source "return { f = function(xs) return xs[1] end }") (Name "f") `shouldSatisfy` isNothing @@ -129,9 +210,22 @@ spec = describe "Foreign lift (#178)" do Set.member (qname "Data.Eq" "refEq") allowlist `shouldBe` True Set.member (qname "Data.Semigroup" "concatString") allowlist `shouldBe` True - it "does not list opaque foreigns" do + it "lists the *.Uncurried run wrappers (#198)" do + Set.member (qname "Data.Function.Uncurried" "runFn2") allowlist `shouldBe` True + Set.member (qname "Data.Function.Uncurried" "runFn10") allowlist `shouldBe` True + Set.member (qname "Control.Monad.ST.Uncurried" "runSTFn1") allowlist + `shouldBe` True + Set.member (qname "Effect.Uncurried" "runEffectFn2") allowlist `shouldBe` True + + it "does not list the mk* wrappers (n-ary AbsN, #24) or opaque foreigns" do Set.member (qname "Data.Ord" "ordArrayImpl") allowlist `shouldBe` False Set.member (qname "Data.Semiring" "numAdd") allowlist `shouldBe` False + Set.member (qname "Data.Function.Uncurried" "mkFn2") allowlist `shouldBe` False + Set.member (qname "Effect.Uncurried" "mkEffectFn2") allowlist `shouldBe` False + -- runFn0/runFn1 are not lifted: runFn0 is a nullary call (no AppN), + -- runFn1 has no foreign implementation (it is PureScript `id`). + Set.member (qname "Data.Function.Uncurried" "runFn0") allowlist `shouldBe` False + Set.member (qname "Data.Function.Uncurried" "runFn1") allowlist `shouldBe` False qname ∷ Text → Text → QName qname m n = QName (moduleNameFromString m) (Name n) diff --git a/test/ps/output/Golden.StringCodePoints.Test/golden.ir b/test/ps/output/Golden.StringCodePoints.Test/golden.ir index 654e2fd9..793012ab 100644 --- a/test/ps/output/Golden.StringCodePoints.Test/golden.ir +++ b/test/ps/output/Golden.StringCodePoints.Test/golden.ir @@ -120,28 +120,28 @@ UberModule ) ), ( PropName "conj", AbsN ( Just Always ) - ( ParamNamed Nothing ( Name "b1$1339" ) :| [] ) + ( ParamNamed Nothing ( Name "b1$1497" ) :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "b2$1340" ) :| [] ) + ( ParamNamed Nothing ( Name "b2$1498" ) :| [] ) ( PrimBinOp Nothing PrimAnd - ( Ref Nothing ( Local ( Name "b1$1339" ) ) ) - ( Ref Nothing ( Local ( Name "b2$1340" ) ) ) + ( Ref Nothing ( Local ( Name "b1$1497" ) ) ) + ( Ref Nothing ( Local ( Name "b2$1498" ) ) ) ) ) ), ( PropName "disj", AbsN ( Just Always ) - ( ParamNamed Nothing ( Name "b1$1337" ) :| [] ) + ( ParamNamed Nothing ( Name "b1$1495" ) :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "b2$1338" ) :| [] ) + ( ParamNamed Nothing ( Name "b2$1496" ) :| [] ) ( PrimBinOp Nothing PrimOr - ( Ref Nothing ( Local ( Name "b1$1337" ) ) ) - ( Ref Nothing ( Local ( Name "b2$1338" ) ) ) + ( Ref Nothing ( Local ( Name "b1$1495" ) ) ) + ( Ref Nothing ( Local ( Name "b2$1496" ) ) ) ) ) ), ( PropName "not", AbsN ( Just Always ) - ( ParamNamed Nothing ( Name "b$1336" ) :| [] ) - ( PrimNot Nothing ( Ref Nothing ( Local ( Name "b$1336" ) ) ) ) + ( ParamNamed Nothing ( Name "b$1494" ) :| [] ) + ( PrimNot Nothing ( Ref Nothing ( Local ( Name "b$1494" ) ) ) ) ) ] ) :| [] @@ -150,12 +150,12 @@ UberModule { qnameModuleName = ModuleName "Data.Eq", qnameName = Name "eqInt" }, LiteralObject Nothing [ ( PropName "eq", AbsN ( Just Always ) - ( ParamNamed Nothing ( Name "r1$1332" ) :| [] ) + ( ParamNamed Nothing ( Name "r1$1490" ) :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "r2$1333" ) :| [] ) + ( ParamNamed Nothing ( Name "r2$1491" ) :| [] ) ( Eq Nothing - ( Ref Nothing ( Local ( Name "r1$1332" ) ) ) - ( Ref Nothing ( Local ( Name "r2$1333" ) ) ) + ( Ref Nothing ( Local ( Name "r1$1490" ) ) ) + ( Ref Nothing ( Local ( Name "r2$1491" ) ) ) ) ) ) @@ -197,19 +197,19 @@ UberModule }, LiteralObject Nothing [ ( PropName "compare", AbsN Nothing - ( ParamNamed Nothing ( Name "x$1316" ) :| [] ) + ( ParamNamed Nothing ( Name "x$1474" ) :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "y$1317" ) :| [] ) + ( ParamNamed Nothing ( Name "y$1475" ) :| [] ) ( IfThenElse Nothing ( PrimBinOp Nothing PrimLt - ( Ref Nothing ( Local ( Name "x$1316" ) ) ) - ( Ref Nothing ( Local ( Name "y$1317" ) ) ) + ( Ref Nothing ( Local ( Name "x$1474" ) ) ) + ( Ref Nothing ( Local ( Name "y$1475" ) ) ) ) ( Ref Nothing ( Imported ( ModuleName "Data.Ordering" ) ( Name "LT" ) ) ) ( IfThenElse Nothing ( Eq Nothing - ( Ref Nothing ( Local ( Name "x$1316" ) ) ) - ( Ref Nothing ( Local ( Name "y$1317" ) ) ) + ( Ref Nothing ( Local ( Name "x$1474" ) ) ) + ( Ref Nothing ( Local ( Name "y$1475" ) ) ) ) ( Ref Nothing ( Imported ( ModuleName "Data.Ordering" ) ( Name "EQ" ) ) ) ( Ref Nothing ( Imported ( ModuleName "Data.Ordering" ) ( Name "GT" ) ) ) @@ -402,7 +402,7 @@ UberModule ( AppN Nothing ( Let Nothing ( Standalone - ( Nothing, Name "x$1316$1440", AppN Nothing + ( Nothing, Name "x$1474$1598", AppN Nothing ( ObjectProp ( Just Always ) ( Ref Nothing ( Imported @@ -416,19 +416,19 @@ UberModule ) :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "y$1317$1441" ) :| [] ) + ( ParamNamed Nothing ( Name "y$1475$1599" ) :| [] ) ( IfThenElse Nothing ( PrimBinOp Nothing PrimLt - ( Ref Nothing ( Local ( Name "x$1316$1440" ) ) ) - ( Ref Nothing ( Local ( Name "y$1317$1441" ) ) ) + ( Ref Nothing ( Local ( Name "x$1474$1598" ) ) ) + ( Ref Nothing ( Local ( Name "y$1475$1599" ) ) ) ) ( Ref Nothing ( Imported ( ModuleName "Data.Ordering" ) ( Name "LT" ) ) ) ( IfThenElse Nothing ( Eq Nothing - ( Ref Nothing ( Local ( Name "x$1316$1440" ) ) ) - ( Ref Nothing ( Local ( Name "y$1317$1441" ) ) ) + ( Ref Nothing ( Local ( Name "x$1474$1598" ) ) ) + ( Ref Nothing ( Local ( Name "y$1475$1599" ) ) ) ) ( Ref Nothing ( Imported ( ModuleName "Data.Ordering" ) ( Name "EQ" ) ) @@ -536,7 +536,7 @@ UberModule ) ( Let Nothing ( Standalone - ( Nothing, Name "v$63$1604", IfThenElse Nothing + ( Nothing, Name "v$63$1762", IfThenElse Nothing ( AppN Nothing ( AppN Nothing ( ObjectProp Nothing @@ -606,16 +606,16 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1604" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1762" ) ) ) ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$63$1604" ) ) ) + ( Ref Nothing ( Local ( Name "v$63$1762" ) ) ) ( PropName "value0" ) ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1604" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1762" ) ) ) ) ) ( IfThenElse Nothing ( AppN Nothing @@ -656,7 +656,7 @@ UberModule ( PrimBinOp Nothing PrimConcat ( Let Nothing ( Standalone - ( Nothing, Name "x$1454$1541$1605", PrimBinOp Nothing PrimAdd + ( Nothing, Name "x$1612$1699$1763", PrimBinOp Nothing PrimAdd ( AppN Nothing ( AppN Nothing ( ObjectProp Nothing @@ -684,7 +684,7 @@ UberModule ) ( Let Nothing ( Standalone - ( Nothing, Name "v$63$1606", IfThenElse Nothing + ( Nothing, Name "v$63$1764", IfThenElse Nothing ( AppN Nothing ( AppN Nothing ( ObjectProp Nothing @@ -703,7 +703,7 @@ UberModule ( Ref Nothing ( Imported ( ModuleName "Data.Ord" ) ( Name "ordInt" ) ) :| [ Ref Nothing - ( Local ( Name "x$1454$1541$1605" ) ), AppN Nothing + ( Local ( Name "x$1612$1699$1763" ) ), AppN Nothing ( ObjectProp ( Just Always ) ( Ref Nothing ( Imported ( ModuleName "Data.Enum" ) ( Name "foreign" ) ) @@ -724,7 +724,7 @@ UberModule ( Ref Nothing ( Imported ( ModuleName "Data.Ord" ) ( Name "ordInt" ) ) :| [ Ref Nothing - ( Local ( Name "x$1454$1541$1605" ) ), AppN Nothing + ( Local ( Name "x$1612$1699$1763" ) ), AppN Nothing ( ObjectProp ( Just Always ) ( Ref Nothing ( Imported ( ModuleName "Data.Enum" ) ( Name "foreign" ) ) @@ -747,7 +747,7 @@ UberModule ) ( PropName "fromCharCode" ) ) - ( Ref Nothing ( Local ( Name "x$1454$1541$1605" ) ) :| [] ) :| [] + ( Ref Nothing ( Local ( Name "x$1612$1699$1763" ) ) :| [] ) :| [] ) ) ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Nothing" ) ) ) @@ -756,16 +756,16 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1606" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1764" ) ) ) ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$63$1606" ) ) ) + ( Ref Nothing ( Local ( Name "v$63$1764" ) ) ) ( PropName "value0" ) ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1606" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1764" ) ) ) ) ) ( IfThenElse Nothing ( AppN Nothing @@ -775,7 +775,7 @@ UberModule ( Ref Nothing ( Imported ( ModuleName "Data.Ord" ) ( Name "ordInt" ) ) :| [ Ref Nothing - ( Local ( Name "x$1454$1541$1605" ) ), AppN Nothing + ( Local ( Name "x$1612$1699$1763" ) ), AppN Nothing ( ObjectProp Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Enum" ) ( Name "foreign" ) ) @@ -812,7 +812,7 @@ UberModule ) ( Let Nothing ( Standalone - ( Nothing, Name "x$1454$1541$1607", PrimBinOp Nothing PrimAdd + ( Nothing, Name "x$1612$1699$1765", PrimBinOp Nothing PrimAdd ( AppN Nothing ( AppN Nothing ( ObjectProp Nothing @@ -840,7 +840,7 @@ UberModule ) ( Let Nothing ( Standalone - ( Nothing, Name "v$63$1608", IfThenElse Nothing + ( Nothing, Name "v$63$1766", IfThenElse Nothing ( AppN Nothing ( AppN Nothing ( ObjectProp Nothing @@ -859,7 +859,7 @@ UberModule ( Ref Nothing ( Imported ( ModuleName "Data.Ord" ) ( Name "ordInt" ) ) :| [ Ref Nothing - ( Local ( Name "x$1454$1541$1607" ) ), AppN Nothing + ( Local ( Name "x$1612$1699$1765" ) ), AppN Nothing ( ObjectProp ( Just Always ) ( Ref Nothing ( Imported ( ModuleName "Data.Enum" ) ( Name "foreign" ) ) @@ -880,7 +880,7 @@ UberModule ( Ref Nothing ( Imported ( ModuleName "Data.Ord" ) ( Name "ordInt" ) ) :| [ Ref Nothing - ( Local ( Name "x$1454$1541$1607" ) ), AppN Nothing + ( Local ( Name "x$1612$1699$1765" ) ), AppN Nothing ( ObjectProp ( Just Always ) ( Ref Nothing ( Imported ( ModuleName "Data.Enum" ) ( Name "foreign" ) ) @@ -903,7 +903,7 @@ UberModule ) ( PropName "fromCharCode" ) ) - ( Ref Nothing ( Local ( Name "x$1454$1541$1607" ) ) :| [] ) :| [] + ( Ref Nothing ( Local ( Name "x$1612$1699$1765" ) ) :| [] ) :| [] ) ) ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Nothing" ) ) ) @@ -912,16 +912,16 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1608" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1766" ) ) ) ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$63$1608" ) ) ) + ( Ref Nothing ( Local ( Name "v$63$1766" ) ) ) ( PropName "value0" ) ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1608" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$63$1766" ) ) ) ) ) ( IfThenElse Nothing ( AppN Nothing @@ -931,7 +931,7 @@ UberModule ( Ref Nothing ( Imported ( ModuleName "Data.Ord" ) ( Name "ordInt" ) ) :| [ Ref Nothing - ( Local ( Name "x$1454$1541$1607" ) ), AppN Nothing + ( Local ( Name "x$1612$1699$1765" ) ), AppN Nothing ( ObjectProp Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Enum" ) ( Name "foreign" ) ) @@ -1233,19 +1233,19 @@ UberModule ( PropName "unfoldrArrayImpl" ) ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "v2$1346$1370" ) :| [] ) + ( ParamNamed Nothing ( Name "v2$1504$1528" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) ( ReflectCtor Nothing - ( Ref Nothing ( Local ( Name "v2$1346$1370" ) ) ) + ( Ref Nothing ( Local ( Name "v2$1504$1528" ) ) ) ) ) ( LiteralBool Nothing True ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) ( ReflectCtor Nothing - ( Ref Nothing ( Local ( Name "v2$1346$1370" ) ) ) + ( Ref Nothing ( Local ( Name "v2$1504$1528" ) ) ) ) ) ( LiteralBool Nothing False ) ( Exception Nothing "No patterns matched" ) @@ -1263,14 +1263,14 @@ UberModule ( AbsN Nothing ( ParamUnused Nothing :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "v$1417" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1575" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1417" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1575" ) ) ) ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1417" ) ) ) + ( Ref Nothing ( Local ( Name "v$1575" ) ) ) ( PropName "value0" ) ) ( Exception Nothing "No patterns matched" ) @@ -1280,17 +1280,17 @@ UberModule ) ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "v$1368" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1526" ) :| [] ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1368" ) ) ) + ( Ref Nothing ( Local ( Name "v$1526" ) ) ) ( PropName "value0" ) ) :| [] ) ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "v$1369" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1527" ) :| [] ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1369" ) ) ) + ( Ref Nothing ( Local ( Name "v$1527" ) ) ) ( PropName "value1" ) ) :| [] ) @@ -1299,7 +1299,7 @@ UberModule ( ParamNamed Nothing ( Name "s$11" ) :| [] ) ( Let Nothing ( Standalone - ( Nothing, Name "v1$1420", AppN Nothing + ( Nothing, Name "v1$1578", AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.String.CodePoints" ) ( Name "uncons" ) ) ) @@ -1309,14 +1309,14 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1420" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1578" ) ) ) ) ) ( AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Just" ) ) ) ( Let Nothing ( Standalone ( Nothing, Name "v$12", ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v1$1420" ) ) ) + ( Ref Nothing ( Local ( Name "v1$1578" ) ) ) ( PropName "value0" ) ) :| [] ) @@ -1649,7 +1649,7 @@ UberModule ( LiteralObject Nothing [ ( PropName "succ", AbsN Nothing - ( ParamNamed Nothing ( Name "a$1405" ) :| [] ) + ( ParamNamed Nothing ( Name "a$1563" ) :| [] ) ( AppN Nothing ( ObjectProp Nothing ( Ref Nothing @@ -1671,14 +1671,14 @@ UberModule ) ( PropName "fromEnum" ) ) - ( Ref Nothing ( Local ( Name "a$1405" ) ) :| [] ) + ( Ref Nothing ( Local ( Name "a$1563" ) ) :| [] ) ) ( LiteralInt Nothing 1 ) :| [] ) ) ), ( PropName "pred", AbsN Nothing - ( ParamNamed Nothing ( Name "a$1413" ) :| [] ) + ( ParamNamed Nothing ( Name "a$1571" ) :| [] ) ( AppN Nothing ( ObjectProp Nothing ( Ref Nothing @@ -1700,7 +1700,7 @@ UberModule ) ( PropName "fromEnum" ) ) - ( Ref Nothing ( Local ( Name "a$1413" ) ) :| [] ) + ( Ref Nothing ( Local ( Name "a$1571" ) ) :| [] ) ) ( LiteralInt Nothing 1 ) :| [] ) @@ -1763,7 +1763,7 @@ UberModule ( QName { qnameModuleName = ModuleName "Golden.StringCodePoints.Test", qnameName = Name "cp" }, AbsN Nothing - ( ParamNamed Nothing ( Name "x$1398$1508" ) :| [] ) + ( ParamNamed Nothing ( Name "x$1556$1666" ) :| [] ) ( AppN Nothing ( AppN Nothing ( ObjectProp ( Just Always ) @@ -1773,14 +1773,14 @@ UberModule ( AbsN Nothing ( ParamUnused Nothing :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "v$1378" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1536" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1378" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1536" ) ) ) ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1378" ) ) ) + ( Ref Nothing ( Local ( Name "v$1536" ) ) ) ( PropName "value0" ) ) ( Exception Nothing "No patterns matched" ) @@ -1795,14 +1795,14 @@ UberModule ) ( PropName "toEnum" ) ) - ( Ref Nothing ( Local ( Name "x$1398$1508" ) ) :| [] ) :| [] + ( Ref Nothing ( Local ( Name "x$1556$1666" ) ) :| [] ) :| [] ) ) ), Standalone ( QName { qnameModuleName = ModuleName "Golden.StringCodePoints.Test", qnameName = Name "codes" }, AbsN Nothing - ( ParamNamed Nothing ( Name "x$1398$1505" ) :| [] ) + ( ParamNamed Nothing ( Name "x$1556$1663" ) :| [] ) ( AppN Nothing ( AppN Nothing ( ObjectProp Nothing @@ -1817,7 +1817,7 @@ UberModule ( Ref Nothing ( Imported ( ModuleName "Data.String.CodePoints" ) ( Name "toCodePointArray" ) ) ) - ( Ref Nothing ( Local ( Name "x$1398$1505" ) ) :| [] ) :| [] + ( Ref Nothing ( Local ( Name "x$1556$1663" ) ) :| [] ) :| [] ) ) ) @@ -2001,11 +2001,11 @@ UberModule ( LiteralObject Nothing [ ( PropName "show", AbsN Nothing - ( ParamNamed Nothing ( Name "v$1384$1561" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1542$1719" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1384$1561" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1542$1719" ) ) ) ) ) ( PrimBinOp Nothing PrimConcat ( LiteralString Nothing "(Just " ) @@ -2018,7 +2018,7 @@ UberModule ( PropName "showIntImpl" ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1384$1561" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1719" ) ) ) ( PropName "value0" ) :| [] ) ) @@ -2029,7 +2029,7 @@ UberModule ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) ( ReflectCtor Nothing - ( Ref Nothing ( Local ( Name "v$1384$1561" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1719" ) ) ) ) ) ( LiteralString Nothing "Nothing" ) @@ -2040,7 +2040,7 @@ UberModule ] :| [ Let Nothing ( Standalone - ( Nothing, Name "v1$1382$1559", AppN Nothing + ( Nothing, Name "v1$1540$1717", AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.String.CodePoints" ) @@ -2053,7 +2053,7 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1382$1559" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1540$1717" ) ) ) ) ) ( AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Just" ) ) ) @@ -2065,7 +2065,7 @@ UberModule ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v1$1382$1559" ) ) ) + ( Ref Nothing ( Local ( Name "v1$1540$1717" ) ) ) ( PropName "value0" ) :| [] ) :| [] ) @@ -2083,11 +2083,11 @@ UberModule ( LiteralObject Nothing [ ( PropName "show", AbsN Nothing - ( ParamNamed Nothing ( Name "v$1384$1569" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1542$1727" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1384$1569" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1542$1727" ) ) ) ) ) ( PrimBinOp Nothing PrimConcat ( LiteralString Nothing "(Just " ) @@ -2100,7 +2100,7 @@ UberModule ( PropName "showIntImpl" ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1384$1569" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1727" ) ) ) ( PropName "value0" ) :| [] ) ) @@ -2111,7 +2111,7 @@ UberModule ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) ( ReflectCtor Nothing - ( Ref Nothing ( Local ( Name "v$1384$1569" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1727" ) ) ) ) ) ( LiteralString Nothing "Nothing" ) @@ -2122,7 +2122,7 @@ UberModule ] :| [ Let Nothing ( Standalone - ( Nothing, Name "v1$1382$1567", AppN Nothing + ( Nothing, Name "v1$1540$1725", AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.String.CodePoints" ) @@ -2135,7 +2135,7 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1382$1567" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1540$1725" ) ) ) ) ) ( AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Just" ) ) ) @@ -2147,7 +2147,7 @@ UberModule ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v1$1382$1567" ) ) ) + ( Ref Nothing ( Local ( Name "v1$1540$1725" ) ) ) ( PropName "value0" ) :| [] ) :| [] ) @@ -2165,11 +2165,11 @@ UberModule ( LiteralObject Nothing [ ( PropName "show", AbsN Nothing - ( ParamNamed Nothing ( Name "v$1384$1577" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1542$1735" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1384$1577" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1542$1735" ) ) ) ) ) ( PrimBinOp Nothing PrimConcat ( LiteralString Nothing "(Just " ) @@ -2182,7 +2182,7 @@ UberModule ( PropName "showIntImpl" ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1384$1577" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1735" ) ) ) ( PropName "value0" ) :| [] ) ) @@ -2193,7 +2193,7 @@ UberModule ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) ( ReflectCtor Nothing - ( Ref Nothing ( Local ( Name "v$1384$1577" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1735" ) ) ) ) ) ( LiteralString Nothing "Nothing" ) @@ -2204,7 +2204,7 @@ UberModule ] :| [ Let Nothing ( Standalone - ( Nothing, Name "v1$1382$1575", AppN Nothing + ( Nothing, Name "v1$1540$1733", AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.String.CodePoints" ) @@ -2217,7 +2217,7 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1382$1575" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1540$1733" ) ) ) ) ) ( AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Just" ) ) ) @@ -2229,7 +2229,7 @@ UberModule ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v1$1382$1575" ) ) ) + ( Ref Nothing ( Local ( Name "v1$1540$1733" ) ) ) ( PropName "value0" ) :| [] ) :| [] ) @@ -2247,11 +2247,11 @@ UberModule ( LiteralObject Nothing [ ( PropName "show", AbsN Nothing - ( ParamNamed Nothing ( Name "v$1384$1588" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1542$1746" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1384$1588" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1542$1746" ) ) ) ) ) ( PrimBinOp Nothing PrimConcat ( LiteralString Nothing "(Just " ) @@ -2264,7 +2264,7 @@ UberModule ( PropName "showIntImpl" ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1384$1588" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1746" ) ) ) ( PropName "value0" ) :| [] ) ) @@ -2275,7 +2275,7 @@ UberModule ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) ( ReflectCtor Nothing - ( Ref Nothing ( Local ( Name "v$1384$1588" ) ) ) + ( Ref Nothing ( Local ( Name "v$1542$1746" ) ) ) ) ) ( LiteralString Nothing "Nothing" ) @@ -2286,7 +2286,7 @@ UberModule ] :| [ Let Nothing ( Standalone - ( Nothing, Name "v1$1382$1586", AppN Nothing + ( Nothing, Name "v1$1540$1744", AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.String.CodePoints" ) ( Name "uncons" ) ) ) @@ -2296,7 +2296,7 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1382$1586" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1540$1744" ) ) ) ) ) ( AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Just" ) ) ) @@ -2309,7 +2309,7 @@ UberModule ) ( ObjectProp Nothing ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v1$1382$1586" ) ) ) + ( Ref Nothing ( Local ( Name "v1$1540$1744" ) ) ) ( PropName "value0" ) ) ( PropName "head" ) :| [] @@ -2329,11 +2329,11 @@ UberModule ( LiteralObject Nothing [ ( PropName "show", AbsN Nothing - ( ParamNamed Nothing ( Name "v$1499" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1657" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1499" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1657" ) ) ) ) ) ( PrimBinOp Nothing PrimConcat ( LiteralString Nothing "(Just " ) @@ -2354,7 +2354,7 @@ UberModule ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1499" ) ) ) + ( Ref Nothing ( Local ( Name "v$1657" ) ) ) ( PropName "value0" ) :| [] ) ) @@ -2364,7 +2364,7 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Nothing" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1499" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v$1657" ) ) ) ) ) ( LiteralString Nothing "Nothing" ) ( Exception Nothing "No patterns matched" ) @@ -2374,7 +2374,7 @@ UberModule ] :| [ Let Nothing ( Standalone - ( Nothing, Name "v1$1382$1601", AppN Nothing + ( Nothing, Name "v1$1540$1759", AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.String.CodePoints" ) ( Name "uncons" ) ) ) @@ -2384,7 +2384,7 @@ UberModule ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) - ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1382$1601" ) ) ) ) + ( ReflectCtor Nothing ( Ref Nothing ( Local ( Name "v1$1540$1759" ) ) ) ) ) ( AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Data.Maybe" ) ( Name "Just" ) ) ) @@ -2412,7 +2412,7 @@ UberModule ) ( ObjectProp Nothing ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v1$1382$1601" ) ) ) + ( Ref Nothing ( Local ( Name "v1$1540$1759" ) ) ) ( PropName "value0" ) ) ( PropName "tail" ) :| [] @@ -2524,16 +2524,16 @@ UberModule ( AbsN Nothing ( ParamUnused Nothing :| [] ) ( AbsN Nothing - ( ParamNamed Nothing ( Name "v$1378$1614" ) :| [] ) + ( ParamNamed Nothing ( Name "v$1536$1772" ) :| [] ) ( IfThenElse Nothing ( Eq Nothing ( LiteralString Nothing "Data.Maybe∷Maybe.Just" ) ( ReflectCtor Nothing - ( Ref Nothing ( Local ( Name "v$1378$1614" ) ) ) + ( Ref Nothing ( Local ( Name "v$1536$1772" ) ) ) ) ) ( ObjectProp Nothing - ( Ref Nothing ( Local ( Name "v$1378$1614" ) ) ) + ( Ref Nothing ( Local ( Name "v$1536$1772" ) ) ) ( PropName "value0" ) ) ( Exception Nothing "No patterns matched" ) diff --git a/test/ps/output/Golden.StringCodePoints.Test/golden.lua b/test/ps/output/Golden.StringCodePoints.Test/golden.lua index 8e30f989..cee55943 100644 --- a/test/ps/output/Golden.StringCodePoints.Test/golden.lua +++ b/test/ps/output/Golden.StringCodePoints.Test/golden.lua @@ -259,17 +259,17 @@ M.Data_HeytingAlgebra_heytingAlgebraBoolean = { return Data_HeytingAlgebra_heytingAlgebraBoolean.disj(Data_HeytingAlgebra_heytingAlgebraBoolean._not_(a))(b) end end, - conj = function(b1_S_1339) - return function(b2_S_1340) return b1_S_1339 and b2_S_1340 end + conj = function(b1_S_1497) + return function(b2_S_1498) return b1_S_1497 and b2_S_1498 end end, - disj = function(b1_S_1337) - return function(b2_S_1338) return b1_S_1337 or b2_S_1338 end + disj = function(b1_S_1495) + return function(b2_S_1496) return b1_S_1495 or b2_S_1496 end end, - _not_ = function(b_S_1336) return not(b_S_1336) end + _not_ = function(b_S_1494) return not(b_S_1494) end } M.Data_Eq_eqInt = { - eq = function(r1_S_1332) - return function(r2_S_1333) return r1_S_1332 == r2_S_1333 end + eq = function(r1_S_1490) + return function(r2_S_1491) return r1_S_1490 == r2_S_1491 end end } M.Data_Show_showInt = { show = M.Data_Show_foreign.showIntImpl } @@ -277,11 +277,11 @@ M.Data_Ordering_LT = { ["$ctor"] = "Data.Ordering∷Ordering.LT" } M.Data_Ordering_GT = { ["$ctor"] = "Data.Ordering∷Ordering.GT" } M.Data_Ordering_EQ = { ["$ctor"] = "Data.Ordering∷Ordering.EQ" } M.Data_Ord_ordInt = { - compare = function(x_S_1316) - return function(y_S_1317) - if x_S_1316 < y_S_1317 then + compare = function(x_S_1474) + return function(y_S_1475) + if x_S_1474 < y_S_1475 then return M.Data_Ordering_LT - elseif x_S_1316 == y_S_1317 then + elseif x_S_1474 == y_S_1475 then return M.Data_Ordering_EQ else return M.Data_Ordering_GT @@ -311,11 +311,11 @@ M.Data_String_CodePoints_unsafeCodePointAt0 = M.Data_String_CodePoints_foreign._ local Data_Ord_lessThanOrEq_S_w, Data_Ord_ordInt, Data_String_CodePoints_conj = M.Data_Ord_lessThanOrEq_S_w, M.Data_Ord_ordInt, M.Data_String_CodePoints_conj local cu0_S_28 = M.Data_String_CodePoints_fromEnum(M.Data_String_Unsafe_foreign.charAt(0)(s_S_27)) if Data_String_CodePoints_conj(Data_String_CodePoints_conj(Data_Ord_lessThanOrEq_S_w(Data_Ord_ordInt, 55296, cu0_S_28))(Data_Ord_lessThanOrEq_S_w(Data_Ord_ordInt, cu0_S_28, 56319)))("Data.Ordering∷Ordering.GT" == ((function( ) - local x_S_1316_S_1440 = M.Data_String_CodeUnits_foreign.length(s_S_27) - return function(y_S_1317_S_1441) - if x_S_1316_S_1440 < y_S_1317_S_1441 then + local x_S_1474_S_1598 = M.Data_String_CodeUnits_foreign.length(s_S_27) + return function(y_S_1475_S_1599) + if x_S_1474_S_1598 < y_S_1475_S_1599 then return M.Data_Ordering_LT - elseif x_S_1316_S_1440 == y_S_1317_S_1441 then + elseif x_S_1474_S_1598 == y_S_1475_S_1599 then return M.Data_Ordering_EQ else return M.Data_Ordering_GT @@ -335,16 +335,16 @@ end) M.Data_String_CodePoints_singletonFallback = function(v) if M.Data_Ord_lessThanOrEq_S_w(M.Data_Ord_ordInt, v, 65535) then return M.Data_String_CodeUnits_foreign.singleton((function() - local v_S_63_S_1604 = (function() + local v_S_63_S_1762 = (function() if M.Data_HeytingAlgebra_heytingAlgebraBoolean.conj(M.Data_Ord_greaterThanOrEq_S_w(M.Data_Ord_ordInt, v, M.Data_Enum_foreign.toCharCode(M.Data_Enum_bottom1)))(M.Data_Ord_lessThanOrEq_S_w(M.Data_Ord_ordInt, v, M.Data_Enum_foreign.toCharCode(M.Data_Enum_top1))) then return M.Data_Maybe_Just(M.Data_Enum_foreign.fromCharCode(v)) else return M.Data_Maybe_Nothing end end)() - if "Data.Maybe∷Maybe.Just" == v_S_63_S_1604["$ctor"] then - return v_S_63_S_1604.value0 - elseif "Data.Maybe∷Maybe.Nothing" == v_S_63_S_1604["$ctor"] then + if "Data.Maybe∷Maybe.Just" == v_S_63_S_1762["$ctor"] then + return v_S_63_S_1762.value0 + elseif "Data.Maybe∷Maybe.Nothing" == v_S_63_S_1762["$ctor"] then if M.Data_Ord_lessThan_S_w(M.Data_Ord_ordInt, v, M.Data_Enum_foreign.toCharCode(M.Data_Bounded_foreign.bottomChar)) then return M.Data_Bounded_foreign.bottomChar else @@ -356,19 +356,19 @@ M.Data_String_CodePoints_singletonFallback = function(v) end)()) else return (function() - local x_S_1454_S_1541_S_1605 = M.Data_EuclideanRing_foreign.intDiv(v - 65536)(1024) + 55296 + local x_S_1612_S_1699_S_1763 = M.Data_EuclideanRing_foreign.intDiv(v - 65536)(1024) + 55296 return M.Data_String_CodeUnits_foreign.singleton((function() - local v_S_63_S_1606 = (function() - if M.Data_HeytingAlgebra_heytingAlgebraBoolean.conj(M.Data_Ord_greaterThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1454_S_1541_S_1605, M.Data_Enum_foreign.toCharCode(M.Data_Enum_bottom1)))(M.Data_Ord_lessThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1454_S_1541_S_1605, M.Data_Enum_foreign.toCharCode(M.Data_Enum_top1))) then - return M.Data_Maybe_Just(M.Data_Enum_foreign.fromCharCode(x_S_1454_S_1541_S_1605)) + local v_S_63_S_1764 = (function() + if M.Data_HeytingAlgebra_heytingAlgebraBoolean.conj(M.Data_Ord_greaterThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1612_S_1699_S_1763, M.Data_Enum_foreign.toCharCode(M.Data_Enum_bottom1)))(M.Data_Ord_lessThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1612_S_1699_S_1763, M.Data_Enum_foreign.toCharCode(M.Data_Enum_top1))) then + return M.Data_Maybe_Just(M.Data_Enum_foreign.fromCharCode(x_S_1612_S_1699_S_1763)) else return M.Data_Maybe_Nothing end end)() - if "Data.Maybe∷Maybe.Just" == v_S_63_S_1606["$ctor"] then - return v_S_63_S_1606.value0 - elseif "Data.Maybe∷Maybe.Nothing" == v_S_63_S_1606["$ctor"] then - if M.Data_Ord_lessThan_S_w(M.Data_Ord_ordInt, x_S_1454_S_1541_S_1605, M.Data_Enum_foreign.toCharCode(M.Data_Bounded_foreign.bottomChar)) then + if "Data.Maybe∷Maybe.Just" == v_S_63_S_1764["$ctor"] then + return v_S_63_S_1764.value0 + elseif "Data.Maybe∷Maybe.Nothing" == v_S_63_S_1764["$ctor"] then + if M.Data_Ord_lessThan_S_w(M.Data_Ord_ordInt, x_S_1612_S_1699_S_1763, M.Data_Enum_foreign.toCharCode(M.Data_Bounded_foreign.bottomChar)) then return M.Data_Bounded_foreign.bottomChar else return M.Data_Bounded_foreign.topChar @@ -378,19 +378,19 @@ M.Data_String_CodePoints_singletonFallback = function(v) end end)()) end)() .. (function() - local x_S_1454_S_1541_S_1607 = M.Data_EuclideanRing_foreign.intMod(v - 65536)(1024) + 56320 + local x_S_1612_S_1699_S_1765 = M.Data_EuclideanRing_foreign.intMod(v - 65536)(1024) + 56320 return M.Data_String_CodeUnits_foreign.singleton((function() - local v_S_63_S_1608 = (function() - if M.Data_HeytingAlgebra_heytingAlgebraBoolean.conj(M.Data_Ord_greaterThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1454_S_1541_S_1607, M.Data_Enum_foreign.toCharCode(M.Data_Enum_bottom1)))(M.Data_Ord_lessThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1454_S_1541_S_1607, M.Data_Enum_foreign.toCharCode(M.Data_Enum_top1))) then - return M.Data_Maybe_Just(M.Data_Enum_foreign.fromCharCode(x_S_1454_S_1541_S_1607)) + local v_S_63_S_1766 = (function() + if M.Data_HeytingAlgebra_heytingAlgebraBoolean.conj(M.Data_Ord_greaterThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1612_S_1699_S_1765, M.Data_Enum_foreign.toCharCode(M.Data_Enum_bottom1)))(M.Data_Ord_lessThanOrEq_S_w(M.Data_Ord_ordInt, x_S_1612_S_1699_S_1765, M.Data_Enum_foreign.toCharCode(M.Data_Enum_top1))) then + return M.Data_Maybe_Just(M.Data_Enum_foreign.fromCharCode(x_S_1612_S_1699_S_1765)) else return M.Data_Maybe_Nothing end end)() - if "Data.Maybe∷Maybe.Just" == v_S_63_S_1608["$ctor"] then - return v_S_63_S_1608.value0 - elseif "Data.Maybe∷Maybe.Nothing" == v_S_63_S_1608["$ctor"] then - if M.Data_Ord_lessThan_S_w(M.Data_Ord_ordInt, x_S_1454_S_1541_S_1607, M.Data_Enum_foreign.toCharCode(M.Data_Bounded_foreign.bottomChar)) then + if "Data.Maybe∷Maybe.Just" == v_S_63_S_1766["$ctor"] then + return v_S_63_S_1766.value0 + elseif "Data.Maybe∷Maybe.Nothing" == v_S_63_S_1766["$ctor"] then + if M.Data_Ord_lessThan_S_w(M.Data_Ord_ordInt, x_S_1612_S_1699_S_1765, M.Data_Enum_foreign.toCharCode(M.Data_Bounded_foreign.bottomChar)) then return M.Data_Bounded_foreign.bottomChar else return M.Data_Bounded_foreign.topChar @@ -458,29 +458,29 @@ M.Data_String_CodePoints_drop_S_w = function(n, s) return Data_String_CodeUnits_foreign.drop(Data_String_CodeUnits_foreign.length(M.Data_String_CodePoints_take_S_w(n, s)))(s) end M.Data_String_CodePoints_toCodePointArray = M.Data_String_CodePoints_foreign._toCodePointArray(function( s_S_10 ) - return M.Data_Unfoldable_foreign.unfoldrArrayImpl(function(v2_S_1346_S_1370) - if "Data.Maybe∷Maybe.Nothing" == v2_S_1346_S_1370["$ctor"] then + return M.Data_Unfoldable_foreign.unfoldrArrayImpl(function(v2_S_1504_S_1528) + if "Data.Maybe∷Maybe.Nothing" == v2_S_1504_S_1528["$ctor"] then return true - elseif "Data.Maybe∷Maybe.Just" == v2_S_1346_S_1370["$ctor"] then + elseif "Data.Maybe∷Maybe.Just" == v2_S_1504_S_1528["$ctor"] then return false else return error("No patterns matched") end end)(M.Partial_Unsafe_foreign._unsafePartial(function() - return function(v_S_1417) - if "Data.Maybe∷Maybe.Just" == v_S_1417["$ctor"] then - return v_S_1417.value0 + return function(v_S_1575) + if "Data.Maybe∷Maybe.Just" == v_S_1575["$ctor"] then + return v_S_1575.value0 else return error("No patterns matched") end end - end))(function(v_S_1368) return v_S_1368.value0 end)(function(v_S_1369) - return v_S_1369.value1 + end))(function(v_S_1526) return v_S_1526.value0 end)(function(v_S_1527) + return v_S_1527.value1 end)(function(s_S_11) - local v1_S_1420 = M.Data_String_CodePoints_uncons(s_S_11) - if "Data.Maybe∷Maybe.Just" == v1_S_1420["$ctor"] then + local v1_S_1578 = M.Data_String_CodePoints_uncons(s_S_11) + if "Data.Maybe∷Maybe.Just" == v1_S_1578["$ctor"] then return M.Data_Maybe_Just((function() - local v_S_12 = v1_S_1420.value0 + local v_S_12 = v1_S_1578.value0 return (function(value0) return function(value1) return { value0 = value0, value1 = value1 } @@ -551,13 +551,13 @@ M.Data_String_CodePoints_boundedEnumCodePoint = { } M.Data_String_CodePoints_Lazy_enumCodePoint = PSLUA_runtime_lazy("enumCodePoint")(function( ) return { - succ = function(a_S_1405) + succ = function(a_S_1563) local Data_String_CodePoints_boundedEnumCodePoint = M.Data_String_CodePoints_boundedEnumCodePoint - return Data_String_CodePoints_boundedEnumCodePoint.toEnum(Data_String_CodePoints_boundedEnumCodePoint.fromEnum(a_S_1405) + 1) + return Data_String_CodePoints_boundedEnumCodePoint.toEnum(Data_String_CodePoints_boundedEnumCodePoint.fromEnum(a_S_1563) + 1) end, - pred = function(a_S_1413) + pred = function(a_S_1571) local Data_String_CodePoints_boundedEnumCodePoint = M.Data_String_CodePoints_boundedEnumCodePoint - return Data_String_CodePoints_boundedEnumCodePoint.toEnum(Data_String_CodePoints_boundedEnumCodePoint.fromEnum(a_S_1413) - 1) + return Data_String_CodePoints_boundedEnumCodePoint.toEnum(Data_String_CodePoints_boundedEnumCodePoint.fromEnum(a_S_1571) - 1) end, Ord0 = function() return M.Data_String_CodePoints_ordCodePoint end } @@ -569,19 +569,19 @@ M.Golden_StringCodePoints_Test_fromEnum = M.Data_String_CodePoints_boundedEnumCo M.Golden_StringCodePoints_Test_showArray = { show = M.Data_Show_foreign.showArrayImpl(M.Data_Show_foreign.showIntImpl) } -M.Golden_StringCodePoints_Test_cp = function(x_S_1398_S_1508) +M.Golden_StringCodePoints_Test_cp = function(x_S_1556_S_1666) return M.Partial_Unsafe_foreign._unsafePartial(function() - return function(v_S_1378) - if "Data.Maybe∷Maybe.Just" == v_S_1378["$ctor"] then - return v_S_1378.value0 + return function(v_S_1536) + if "Data.Maybe∷Maybe.Just" == v_S_1536["$ctor"] then + return v_S_1536.value0 else return error("No patterns matched") end end - end)(M.Data_String_CodePoints_boundedEnumCodePoint.toEnum(x_S_1398_S_1508)) + end)(M.Data_String_CodePoints_boundedEnumCodePoint.toEnum(x_S_1556_S_1666)) end -M.Golden_StringCodePoints_Test_codes = function(x_S_1398_S_1505) - return M.Data_Functor_foreign.arrayMap(M.Golden_StringCodePoints_Test_fromEnum)(M.Data_String_CodePoints_toCodePointArray(x_S_1398_S_1505)) +M.Golden_StringCodePoints_Test_codes = function(x_S_1556_S_1663) + return M.Data_Functor_foreign.arrayMap(M.Golden_StringCodePoints_Test_fromEnum)(M.Data_String_CodePoints_toCodePointArray(x_S_1556_S_1663)) end return (function() local Effect_Console_logShow_S_w, Data_String_CodePoints_toCodePointArray, Data_Functor_foreign, Golden_StringCodePoints_Test_fromEnum, Golden_StringCodePoints_Test_showArray, Data_String_CodePoints_codePointAt_S_w, Data_Show_showInt, Data_String_CodePoints_uncons = M.Effect_Console_logShow_S_w, M.Data_String_CodePoints_toCodePointArray, M.Data_Functor_foreign, M.Golden_StringCodePoints_Test_fromEnum, M.Golden_StringCodePoints_Test_showArray, M.Data_String_CodePoints_codePointAt_S_w, M.Data_Show_showInt, M.Data_String_CodePoints_uncons @@ -591,91 +591,91 @@ return (function() local _ = Effect_Console_logShow_S_w(Golden_StringCodePoints_Test_showArray, Data_Functor_foreign.arrayMap(Golden_StringCodePoints_Test_fromEnum)(Data_String_CodePoints_toCodePointArray(M.Data_String_CodePoints_take_S_w(2, "aéЯ𝐀z"))))() local _ = Effect_Console_logShow_S_w(Golden_StringCodePoints_Test_showArray, Data_Functor_foreign.arrayMap(Golden_StringCodePoints_Test_fromEnum)(Data_String_CodePoints_toCodePointArray(M.Data_String_CodePoints_drop_S_w(2, "aéЯ𝐀z"))))() local _ = Effect_Console_logShow_S_w({ - show = function(v_S_1384_S_1561) - if "Data.Maybe∷Maybe.Just" == v_S_1384_S_1561["$ctor"] then - return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1384_S_1561.value0) .. ")" - elseif "Data.Maybe∷Maybe.Nothing" == v_S_1384_S_1561["$ctor"] then + show = function(v_S_1542_S_1719) + if "Data.Maybe∷Maybe.Just" == v_S_1542_S_1719["$ctor"] then + return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1542_S_1719.value0) .. ")" + elseif "Data.Maybe∷Maybe.Nothing" == v_S_1542_S_1719["$ctor"] then return "Nothing" else return error("No patterns matched") end end }, (function() - local v1_S_1382_S_1559 = Data_String_CodePoints_codePointAt_S_w(0, "aéЯ𝐀z") - if "Data.Maybe∷Maybe.Just" == v1_S_1382_S_1559["$ctor"] then - return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1382_S_1559.value0)) + local v1_S_1540_S_1717 = Data_String_CodePoints_codePointAt_S_w(0, "aéЯ𝐀z") + if "Data.Maybe∷Maybe.Just" == v1_S_1540_S_1717["$ctor"] then + return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1540_S_1717.value0)) else return M.Data_Maybe_Nothing end end)())() local _ = Effect_Console_logShow_S_w({ - show = function(v_S_1384_S_1569) - if "Data.Maybe∷Maybe.Just" == v_S_1384_S_1569["$ctor"] then - return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1384_S_1569.value0) .. ")" - elseif "Data.Maybe∷Maybe.Nothing" == v_S_1384_S_1569["$ctor"] then + show = function(v_S_1542_S_1727) + if "Data.Maybe∷Maybe.Just" == v_S_1542_S_1727["$ctor"] then + return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1542_S_1727.value0) .. ")" + elseif "Data.Maybe∷Maybe.Nothing" == v_S_1542_S_1727["$ctor"] then return "Nothing" else return error("No patterns matched") end end }, (function() - local v1_S_1382_S_1567 = Data_String_CodePoints_codePointAt_S_w(3, "aéЯ𝐀z") - if "Data.Maybe∷Maybe.Just" == v1_S_1382_S_1567["$ctor"] then - return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1382_S_1567.value0)) + local v1_S_1540_S_1725 = Data_String_CodePoints_codePointAt_S_w(3, "aéЯ𝐀z") + if "Data.Maybe∷Maybe.Just" == v1_S_1540_S_1725["$ctor"] then + return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1540_S_1725.value0)) else return M.Data_Maybe_Nothing end end)())() local _ = Effect_Console_logShow_S_w({ - show = function(v_S_1384_S_1577) - if "Data.Maybe∷Maybe.Just" == v_S_1384_S_1577["$ctor"] then - return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1384_S_1577.value0) .. ")" - elseif "Data.Maybe∷Maybe.Nothing" == v_S_1384_S_1577["$ctor"] then + show = function(v_S_1542_S_1735) + if "Data.Maybe∷Maybe.Just" == v_S_1542_S_1735["$ctor"] then + return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1542_S_1735.value0) .. ")" + elseif "Data.Maybe∷Maybe.Nothing" == v_S_1542_S_1735["$ctor"] then return "Nothing" else return error("No patterns matched") end end }, (function() - local v1_S_1382_S_1575 = Data_String_CodePoints_codePointAt_S_w(5, "aéЯ𝐀z") - if "Data.Maybe∷Maybe.Just" == v1_S_1382_S_1575["$ctor"] then - return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1382_S_1575.value0)) + local v1_S_1540_S_1733 = Data_String_CodePoints_codePointAt_S_w(5, "aéЯ𝐀z") + if "Data.Maybe∷Maybe.Just" == v1_S_1540_S_1733["$ctor"] then + return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1540_S_1733.value0)) else return M.Data_Maybe_Nothing end end)())() local _ = Effect_Console_logShow_S_w({ - show = function(v_S_1384_S_1588) - if "Data.Maybe∷Maybe.Just" == v_S_1384_S_1588["$ctor"] then - return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1384_S_1588.value0) .. ")" - elseif "Data.Maybe∷Maybe.Nothing" == v_S_1384_S_1588["$ctor"] then + show = function(v_S_1542_S_1746) + if "Data.Maybe∷Maybe.Just" == v_S_1542_S_1746["$ctor"] then + return "(Just " .. M.Data_Show_foreign.showIntImpl(v_S_1542_S_1746.value0) .. ")" + elseif "Data.Maybe∷Maybe.Nothing" == v_S_1542_S_1746["$ctor"] then return "Nothing" else return error("No patterns matched") end end }, (function() - local v1_S_1382_S_1586 = Data_String_CodePoints_uncons("aéЯ𝐀z") - if "Data.Maybe∷Maybe.Just" == v1_S_1382_S_1586["$ctor"] then - return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1382_S_1586.value0.head)) + local v1_S_1540_S_1744 = Data_String_CodePoints_uncons("aéЯ𝐀z") + if "Data.Maybe∷Maybe.Just" == v1_S_1540_S_1744["$ctor"] then + return M.Data_Maybe_Just(Golden_StringCodePoints_Test_fromEnum(v1_S_1540_S_1744.value0.head)) else return M.Data_Maybe_Nothing end end)())() local _ = Effect_Console_logShow_S_w({ - show = function(v_S_1499) - if "Data.Maybe∷Maybe.Just" == v_S_1499["$ctor"] then - return "(Just " .. M.Data_Show_foreign.showArrayImpl(M.Data_Show_foreign.showIntImpl)(v_S_1499.value0) .. ")" - elseif "Data.Maybe∷Maybe.Nothing" == v_S_1499["$ctor"] then + show = function(v_S_1657) + if "Data.Maybe∷Maybe.Just" == v_S_1657["$ctor"] then + return "(Just " .. M.Data_Show_foreign.showArrayImpl(M.Data_Show_foreign.showIntImpl)(v_S_1657.value0) .. ")" + elseif "Data.Maybe∷Maybe.Nothing" == v_S_1657["$ctor"] then return "Nothing" else return error("No patterns matched") end end }, (function() - local v1_S_1382_S_1601 = Data_String_CodePoints_uncons("aéЯ𝐀z") - if "Data.Maybe∷Maybe.Just" == v1_S_1382_S_1601["$ctor"] then - return M.Data_Maybe_Just(Data_Functor_foreign.arrayMap(Golden_StringCodePoints_Test_fromEnum)(Data_String_CodePoints_toCodePointArray(v1_S_1382_S_1601.value0.tail))) + local v1_S_1540_S_1759 = Data_String_CodePoints_uncons("aéЯ𝐀z") + if "Data.Maybe∷Maybe.Just" == v1_S_1540_S_1759["$ctor"] then + return M.Data_Maybe_Just(Data_Functor_foreign.arrayMap(Golden_StringCodePoints_Test_fromEnum)(Data_String_CodePoints_toCodePointArray(v1_S_1540_S_1759.value0.tail))) else return M.Data_Maybe_Nothing end @@ -692,9 +692,9 @@ return (function() end }, M.Data_String_CodePoints_foreign._fromCodePointArray(M.Data_String_CodePoints_singletonFallback)(Data_String_CodePoints_toCodePointArray("aéЯ𝐀z")) == "aéЯ𝐀z")() return Effect_Console_logShow_S_w(Golden_StringCodePoints_Test_showArray, Data_Functor_foreign.arrayMap(Golden_StringCodePoints_Test_fromEnum)(Data_String_CodePoints_toCodePointArray(M.Data_String_CodePoints_singleton(M.Partial_Unsafe_foreign._unsafePartial(function( ) - return function(v_S_1378_S_1614) - if "Data.Maybe∷Maybe.Just" == v_S_1378_S_1614["$ctor"] then - return v_S_1378_S_1614.value0 + return function(v_S_1536_S_1772) + if "Data.Maybe∷Maybe.Just" == v_S_1536_S_1772["$ctor"] then + return v_S_1536_S_1772.value0 else return error("No patterns matched") end diff --git a/test/ps/output/Golden.UncurriedLift.Test/corefn.json b/test/ps/output/Golden.UncurriedLift.Test/corefn.json new file mode 100644 index 00000000..24cd03e7 --- /dev/null +++ b/test/ps/output/Golden.UncurriedLift.Test/corefn.json @@ -0,0 +1 @@ +{"builtWith":"0.15.16","comments":[{"LineComment":" | Exercises the lifting of the @*.Uncurried@ run wrappers to direct"},{"LineComment":" | n-ary calls (issue #198)."},{"LineComment":" |"},{"LineComment":" | The pure @runFn2@/@runFn3@ sites must collapse to a single Lua call"},{"LineComment":" | (@add3(1, 2, 3)@), not the curried-onion @runFn3(add3)(1)(2)(3)@. The"},{"LineComment":" | effectful @runEffectFn2@ site sits in statement position, where magicDo"},{"LineComment":" | fuses the run wrapper's thunk away to a direct @logTwice(a, b)@ — one"},{"LineComment":" | call and no closures where the fallback paid four calls and three."}],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[22,25],"start":[22,24]}},"type":"Var","value":{"identifier":"mul","moduleName":["Data","Semiring"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[22,27],"start":[22,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"semiringInt","moduleName":["Data","Semiring"]}},"type":"App"},"identifier":"mul"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[26,8],"start":[26,3]}},"type":"Var","value":{"identifier":"discard","moduleName":["Control","Bind"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discardUnit","moduleName":["Control","Bind"]}},"type":"App"},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"bindEffect","moduleName":["Effect"]}},"type":"App"},"identifier":"discard"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[19,31],"start":[19,30]}},"type":"Var","value":{"identifier":"add","moduleName":["Data","Semiring"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"semiringInt","moduleName":["Data","Semiring"]}},"type":"App"},"identifier":"add"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[42,10],"start":[42,3]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Effect","Console"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"showInt","moduleName":["Data","Show"]}},"type":"App"},"identifier":"logShow"},{"annotation":{"meta":null,"sourceSpan":{"end":[21,24],"start":[21,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[22,13],"start":[22,8]}},"type":"Var","value":{"identifier":"mkFn2","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,14]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,14]}},"argument":"b","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"mul","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[22,23],"start":[22,22]}},"type":"Var","value":{"identifier":"a","sourcePos":[22,15]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,26]}},"type":"Var","value":{"identifier":"b","sourcePos":[22,17]}},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"mul2"},{"annotation":{"meta":null,"sourceSpan":{"end":[24,41],"start":[24,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[25,23],"start":[25,12]}},"type":"Var","value":{"identifier":"mkEffectFn2","moduleName":["Effect","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[25,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[25,24]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[25,24]}},"argument":"b","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[26,6],"start":[26,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,7]}},"type":"Var","value":{"identifier":"a","sourcePos":[25,25]}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[27,6],"start":[27,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[27,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[27,7]}},"type":"Var","value":{"identifier":"b","sourcePos":[25,27]}},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"logTwice"},{"annotation":{"meta":null,"sourceSpan":{"end":[18,28],"start":[18,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[19,13],"start":[19,8]}},"type":"Var","value":{"identifier":"mkFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,14]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,14]}},"argument":"b","body":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,14]}},"argument":"c","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"add","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"add","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,25],"start":[19,24]}},"type":"Var","value":{"identifier":"a","sourcePos":[19,15]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,29],"start":[19,28]}},"type":"Var","value":{"identifier":"b","sourcePos":[19,17]}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,32]}},"type":"Var","value":{"identifier":"c","sourcePos":[19,19]}},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"add3"},{"annotation":{"meta":null,"sourceSpan":{"end":[34,30],"start":[34,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[35,25],"start":[35,19]}},"type":"Var","value":{"identifier":"runFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[35,30],"start":[35,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[35,30],"start":[35,26]}},"type":"Var","value":{"identifier":"add3","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[35,32],"start":[35,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[35,32],"start":[35,31]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[35,34],"start":[35,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[35,34],"start":[35,33]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"App"},"identifier":"addOnePlusTwoTo"},{"annotation":{"meta":null,"sourceSpan":{"end":[37,20],"start":[37,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[41,15],"start":[41,3]}},"type":"Var","value":{"identifier":"runEffectFn2","moduleName":["Effect","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[41,24],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,24],"start":[41,16]}},"type":"Var","value":{"identifier":"logTwice","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[41,32],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,32],"start":[41,25]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"hello"}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,33]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"world"}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[42,18],"start":[42,12]}},"type":"Var","value":{"identifier":"runFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[42,23],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,23],"start":[42,19]}},"type":"Var","value":{"identifier":"add3","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,25],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,25],"start":[42,24]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,27],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,27],"start":[42,26]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,29],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,29],"start":[42,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":3}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[43,18],"start":[43,12]}},"type":"Var","value":{"identifier":"runFn2","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[43,23],"start":[43,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,23],"start":[43,19]}},"type":"Var","value":{"identifier":"mul2","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[43,25],"start":[43,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,25],"start":[43,24]}},"type":"Literal","value":{"literalType":"IntLiteral","value":4}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[43,27],"start":[43,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,27],"start":[43,26]}},"type":"Literal","value":{"literalType":"IntLiteral","value":5}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[44,27],"start":[44,12]}},"type":"Var","value":{"identifier":"addOnePlusTwoTo","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[44,31],"start":[44,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[44,31],"start":[44,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":100}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[45,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[45,27],"start":[45,12]}},"type":"Var","value":{"identifier":"addOnePlusTwoTo","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[45,31],"start":[45,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[45,31],"start":[45,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":200}},"type":"App"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"identifier":"main"}],"exports":["add3","mul2","logTwice","addOnePlusTwoTo","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Control","Bind"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Data","Function","Uncurried"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Data","Semiring"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Data","Show"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Effect"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Effect","Console"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Effect","Uncurried"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Golden","UncurriedLift","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[11,15],"start":[11,1]}},"moduleName":["Prelude"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","UncurriedLift","Test"],"modulePath":"src/Golden/UncurriedLift/Test.purs","reExports":{},"sourceSpan":{"end":[45,32],"start":[9,1]}} \ No newline at end of file diff --git a/test/ps/output/Golden.UncurriedLift.Test/eval/.gitignore b/test/ps/output/Golden.UncurriedLift.Test/eval/.gitignore new file mode 100644 index 00000000..d2dc29bb --- /dev/null +++ b/test/ps/output/Golden.UncurriedLift.Test/eval/.gitignore @@ -0,0 +1 @@ +actual.txt diff --git a/test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt b/test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt new file mode 100644 index 00000000..528a2d35 --- /dev/null +++ b/test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt @@ -0,0 +1,6 @@ +hello +world +6 +20 +103 +203 diff --git a/test/ps/output/Golden.UncurriedLift.Test/golden.ir b/test/ps/output/Golden.UncurriedLift.Test/golden.ir new file mode 100644 index 00000000..13348de2 --- /dev/null +++ b/test/ps/output/Golden.UncurriedLift.Test/golden.ir @@ -0,0 +1,250 @@ +UberModule + { uberModuleBindings = + [ Standalone + ( QName + { qnameModuleName = ModuleName "Data.Show", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Data.Show" ) ".spago/p/prelude/26c058c2a053cf4dd7240f0d822ec096c0fecbe1/src/Data/Show.purs" + [ ( Nothing, Name "showIntImpl" ) ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Data.Function.Uncurried", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Data.Function.Uncurried" ) ".spago/p/functions/03cdfb3561c4e055a53bdba2c491ed3e063eb468/src/Data/Function/Uncurried.purs" + [ ( Nothing, Name "mkFn2" ), ( Nothing, Name "mkFn3" ) ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Effect.Console", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Effect.Console" ) ".spago/p/console/f82835a0b873aafe6bd7b14dd30cc150553d4ab9/src/Effect/Console.purs" + [ ( Nothing, Name "log" ) ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Effect.Uncurried", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Effect.Uncurried" ) ".spago/p/effect/82bac3dff904fa34534c4f5b9deeb5da359471c8/src/Effect/Uncurried.purs" + [ ( Nothing, Name "mkEffectFn2" ) ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.UncurriedLift.Test", qnameName = Name "mul2" + }, AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Data.Function.Uncurried" ) ( Name "foreign" ) ) ) + ( PropName "mkFn2" ) + ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "a" ) :| [] ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "b" ) :| [] ) + ( PrimBinOp Nothing PrimMul + ( Ref Nothing ( Local ( Name "a" ) ) ) + ( Ref Nothing ( Local ( Name "b" ) ) ) + ) + ) :| [] + ) + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.UncurriedLift.Test", qnameName = Name "logTwice" + }, AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Uncurried" ) ( Name "foreign" ) ) ) + ( PropName "mkEffectFn2" ) + ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "a" ) :| [] ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "b" ) :| [] ) + ( AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( Let Nothing + ( Standalone + ( Nothing, Name "_", AppN Nothing + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) + ) + ( PropName "log" ) + ) + ( Ref Nothing ( Local ( Name "a" ) ) :| [] ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ) :| [] + ) + ( AppN Nothing + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) + ) + ( PropName "log" ) + ) + ( Ref Nothing ( Local ( Name "b" ) ) :| [] ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ) + ) + ) + ) :| [] + ) + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.UncurriedLift.Test", qnameName = Name "add3" + }, AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Data.Function.Uncurried" ) ( Name "foreign" ) ) ) + ( PropName "mkFn3" ) + ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "a" ) :| [] ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "b" ) :| [] ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "c" ) :| [] ) + ( PrimBinOp Nothing PrimAdd + ( PrimBinOp Nothing PrimAdd + ( Ref Nothing ( Local ( Name "a" ) ) ) + ( Ref Nothing ( Local ( Name "b" ) ) ) + ) + ( Ref Nothing ( Local ( Name "c" ) ) ) + ) + ) + ) :| [] + ) + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.UncurriedLift.Test", qnameName = Name "addOnePlusTwoTo" + }, AbsN Nothing + ( ParamNamed Nothing ( Name "c$314" ) :| [] ) + ( AppN Nothing + ( Ref Nothing ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) ) + ( LiteralInt Nothing 1 :| + [ LiteralInt Nothing 2, Ref Nothing ( Local ( Name "c$314" ) ) ] + ) + ) + ) + ], uberModuleForeigns = [], uberModuleExports = + [ + ( Name "add3", Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) + ), + ( Name "mul2", Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "mul2" ) ) + ), + ( Name "logTwice", Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "logTwice" ) ) + ), + ( Name "addOnePlusTwoTo", Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "addOnePlusTwoTo" ) ) + ), + ( Name "main", AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( Let Nothing + ( Standalone + ( Nothing, Name "_", AppN Nothing + ( AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "logTwice" ) ) + ) + ( LiteralString Nothing "hello" :| [ LiteralString Nothing "world" ] ) + ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ) :| + [ Standalone + ( Nothing, Name "_", AppN Nothing + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) ) + ( PropName "log" ) + ) + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Data.Show" ) ( Name "foreign" ) ) ) + ( PropName "showIntImpl" ) + ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) + ) + ( LiteralInt Nothing 1 :| + [ LiteralInt Nothing 2, LiteralInt Nothing 3 ] + ) :| [] + ) :| [] + ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ), Standalone + ( Nothing, Name "_", AppN Nothing + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) ) + ( PropName "log" ) + ) + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Data.Show" ) ( Name "foreign" ) ) ) + ( PropName "showIntImpl" ) + ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "mul2" ) ) + ) + ( LiteralInt Nothing 4 :| [ LiteralInt Nothing 5 ] ) :| [] + ) :| [] + ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ), Standalone + ( Nothing, Name "_", AppN Nothing + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) ) + ( PropName "log" ) + ) + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Data.Show" ) ( Name "foreign" ) ) ) + ( PropName "showIntImpl" ) + ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) + ) + ( LiteralInt Nothing 1 :| + [ LiteralInt Nothing 2, LiteralInt Nothing 100 ] + ) :| [] + ) :| [] + ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ) + ] + ) + ( AppN Nothing + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) ) + ( PropName "log" ) + ) + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Data.Show" ) ( Name "foreign" ) ) ) + ( PropName "showIntImpl" ) + ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) + ) + ( LiteralInt Nothing 1 :| [ LiteralInt Nothing 2, LiteralInt Nothing 200 ] ) :| [] + ) :| [] + ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ) + ) + ) + ] + } \ No newline at end of file diff --git a/test/ps/output/Golden.UncurriedLift.Test/golden.lua b/test/ps/output/Golden.UncurriedLift.Test/golden.lua new file mode 100644 index 00000000..6b2432e2 --- /dev/null +++ b/test/ps/output/Golden.UncurriedLift.Test/golden.lua @@ -0,0 +1,38 @@ +local M = {} +M.Data_Show_foreign = { showIntImpl = function(n) return tostring(n) end } +M.Data_Function_Uncurried_foreign = { + mkFn2 = function(fn) return function(a, b) return fn(a)(b) end end, + mkFn3 = function(fn) return function(a, b, c) return fn(a)(b)(c) end end +} +M.Effect_Console_foreign = { + log = function(s) return function() print(s) end end +} +M.Effect_Uncurried_foreign = { + mkEffectFn2 = function(fn) return function(a, b) return fn(a)(b)() end end +} +M.Golden_UncurriedLift_Test_mul2 = M.Data_Function_Uncurried_foreign.mkFn2(function( a ) + return function(b) return a * b end +end) +M.Golden_UncurriedLift_Test_logTwice = M.Effect_Uncurried_foreign.mkEffectFn2(function( a ) + return function(b) + return function() + local Effect_Console_foreign = M.Effect_Console_foreign + local _ = Effect_Console_foreign.log(a)() + return Effect_Console_foreign.log(b)() + end + end +end) +M.Golden_UncurriedLift_Test_add3 = M.Data_Function_Uncurried_foreign.mkFn3(function( a ) + return function(b) return function(c) return a + b + c end end +end) +M.Golden_UncurriedLift_Test_addOnePlusTwoTo = function(c_S_314) + return M.Golden_UncurriedLift_Test_add3(1, 2, c_S_314) +end +return (function() + local Data_Show_foreign, Effect_Console_foreign, Golden_UncurriedLift_Test_add3 = M.Data_Show_foreign, M.Effect_Console_foreign, M.Golden_UncurriedLift_Test_add3 + local _ = M.Golden_UncurriedLift_Test_logTwice("hello", "world") + local _ = Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(Golden_UncurriedLift_Test_add3(1, 2, 3)))() + local _ = Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(M.Golden_UncurriedLift_Test_mul2(4, 5)))() + local _ = Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(Golden_UncurriedLift_Test_add3(1, 2, 100)))() + return Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(Golden_UncurriedLift_Test_add3(1, 2, 200)))() +end)() diff --git a/test/ps/spago.lock b/test/ps/spago.lock index 257880ed..f002ac1e 100644 --- a/test/ps/spago.lock +++ b/test/ps/spago.lock @@ -11,6 +11,7 @@ "either", "enums", "foldable-traversable", + "functions", "maybe", "newtype", "partial", diff --git a/test/ps/spago.yaml b/test/ps/spago.yaml index 384dc10f..27ade0a4 100644 --- a/test/ps/spago.yaml +++ b/test/ps/spago.yaml @@ -16,6 +16,7 @@ package: - either - enums - foldable-traversable + - functions - maybe - newtype - partial diff --git a/test/ps/src/Golden/UncurriedLift/Test.purs b/test/ps/src/Golden/UncurriedLift/Test.purs new file mode 100644 index 00000000..63e1cb5c --- /dev/null +++ b/test/ps/src/Golden/UncurriedLift/Test.purs @@ -0,0 +1,45 @@ +-- | Exercises the lifting of the @*.Uncurried@ run wrappers to direct +-- | n-ary calls (issue #198). +-- | +-- | The pure @runFn2@/@runFn3@ sites must collapse to a single Lua call +-- | (@add3(1, 2, 3)@), not the curried-onion @runFn3(add3)(1)(2)(3)@. The +-- | effectful @runEffectFn2@ site sits in statement position, where magicDo +-- | fuses the run wrapper's thunk away to a direct @logTwice(a, b)@ — one +-- | call and no closures where the fallback paid four calls and three. +module Golden.UncurriedLift.Test where + +import Prelude + +import Data.Function.Uncurried (Fn2, Fn3, mkFn2, mkFn3, runFn2, runFn3) +import Effect (Effect) +import Effect.Console (log, logShow) +import Effect.Uncurried (EffectFn2, mkEffectFn2, runEffectFn2) + +add3 :: Fn3 Int Int Int Int +add3 = mkFn3 \a b c -> a + b + c + +mul2 :: Fn2 Int Int Int +mul2 = mkFn2 \a b -> a * b + +logTwice :: EffectFn2 String String Unit +logTwice = mkEffectFn2 \a b -> do + log a + log b + +-- A partial application: `runFn3 add3 1 2` supplies only two of add3's +-- three arguments, so this exported binding stays a function of the last — +-- lifted to a direct n-ary `add3(1, 2, c)`, the wrapper's curried-fallback +-- semantics without its closures. (Its saturated call sites in `main` +-- additionally inline to `add3(1, 2, n)`.) +addOnePlusTwoTo :: Int -> Int +addOnePlusTwoTo = runFn3 add3 1 2 + +main :: Effect Unit +main = do + -- A non-tail effect statement: magicDo fuses the run wrapper's thunk + -- away, so this becomes a direct `local _ = logTwice("hello", "world")`. + runEffectFn2 logTwice "hello" "world" -- hello / world + logShow (runFn3 add3 1 2 3) -- 6 + logShow (runFn2 mul2 4 5) -- 20 + logShow (addOnePlusTwoTo 100) -- 103 + logShow (addOnePlusTwoTo 200) -- 203 From acd0d3c121b33d0605869bde808558d069cbc794 Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Fri, 10 Jul 2026 17:47:02 +0200 Subject: [PATCH 2/6] chore(bench): accept ArrayFoldl counter goldens (#198) Lifting the uncurried Array/ST wrappers to direct n-ary calls removes three closure allocations from the ArrayFoldl macro bench (total FNEW 17 -> 14; main-chunk 6 -> 5, function-body 11 -> 9). The trace report shifts by line number only. The other bench artifacts are unchanged. --- bench/goldens/fnew_Bench.ArrayFoldl.txt | 20 +++++++++----------- bench/goldens/trace_array_foldl.txt | 8 ++++---- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/bench/goldens/fnew_Bench.ArrayFoldl.txt b/bench/goldens/fnew_Bench.ArrayFoldl.txt index 1158eeee..8f65f367 100644 --- a/bench/goldens/fnew_Bench.ArrayFoldl.txt +++ b/bench/goldens/fnew_Bench.ArrayFoldl.txt @@ -1,18 +1,16 @@ chunk: Bench.ArrayFoldl.lua runtime: LuaJIT 2.1.1741730670 -main-chunk FNEW: 6 -function-body FNEW: 11 -total FNEW: 17 -prototypes: 18 +main-chunk FNEW: 5 +function-body FNEW: 9 +total FNEW: 14 +prototypes: 15 function-body FNEW sites: Bench.ArrayFoldl.lua:11 Bench.ArrayFoldl.lua:10 Bench.ArrayFoldl.lua:21 Bench.ArrayFoldl.lua:20 - Bench.ArrayFoldl.lua:26 - Bench.ArrayFoldl.lua:26 - Bench.ArrayFoldl.lua:49 - Bench.ArrayFoldl.lua:48 - Bench.ArrayFoldl.lua:47 - Bench.ArrayFoldl.lua:56 - Bench.ArrayFoldl.lua:55 + Bench.ArrayFoldl.lua:44 + Bench.ArrayFoldl.lua:43 + Bench.ArrayFoldl.lua:42 + Bench.ArrayFoldl.lua:51 + Bench.ArrayFoldl.lua:50 diff --git a/bench/goldens/trace_array_foldl.txt b/bench/goldens/trace_array_foldl.txt index 2b89bffb..bc930b41 100644 --- a/bench/goldens/trace_array_foldl.txt +++ b/bench/goldens/trace_array_foldl.txt @@ -2,12 +2,12 @@ spec: array_foldl runtime: LuaJIT 2.1.1741730670 workload: n=5000000 reps=2 result=12500002500000 aborts (distinct site -- reason): - Bench.ArrayFoldl.lua:55 -- NYI: bytecode FNEW + Bench.ArrayFoldl.lua:50 -- NYI: bytecode FNEW bytecode end state (J*=compiled, I*=blacklisted): Bench.ArrayFoldl.lua:18 IFORL - Bench.ArrayFoldl.lua:34 JLOOP - Bench.ArrayFoldl.lua:54 IFUNCF - Bench.ArrayFoldl.lua:55 JFUNCF + Bench.ArrayFoldl.lua:29 JLOOP + Bench.ArrayFoldl.lua:49 IFUNCF + Bench.ArrayFoldl.lua:50 JFUNCF array_foldl.lua:13 JFORI array_foldl.lua:13 JFORL array_foldl.lua:17 JFORI From 188e32d21a9a4ee6d02b80fa417825735ae28e0c Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Sat, 11 Jul 2026 11:20:44 +0200 Subject: [PATCH 3/6] fix(foreign-lift): decline literal-lambda calls at a mismatched arity (#198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FunctionCall lift accepted any argument count on a lifted head, so an allowlisted export calling an inlined header-local lambda (or a parenthesized function literal) at the wrong arity would build an ill-formed AppN — violating the WellApplied invariant instead of falling back to an opaque foreign. Guard the case: a literal-AbsN head must be applied at exactly its own parameter count; a mismatch declines. Also correct the surrounding docs found in review: the effect thunk is run by magic-do but shed at code generation (not "fused via magicDo"), fix an unparseable comment sentence in the fromIR special case, and wrap the new spec lines to the 80-column limit. --- lib/Language/PureScript/Backend/Lua.hs | 4 +- .../PureScript/Backend/Lua/ForeignLift.hs | 29 ++++++++---- .../Backend/Lua/ForeignLift/Spec.hs | 47 +++++++++++++------ 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/lib/Language/PureScript/Backend/Lua.hs b/lib/Language/PureScript/Backend/Lua.hs index 9d72daa9..b1f8cda8 100644 --- a/lib/Language/PureScript/Backend/Lua.hs +++ b/lib/Language/PureScript/Backend/Lua.hs @@ -239,8 +239,8 @@ fromIR foreigns topLevelNames modname ir = case ir of pure . Right $ case body of Left chunk → Lua.functionDef luaParams chunk Right e → Lua.functionDef luaParams [Lua.return e] - -- Running the literal thunk a saturated lifted @*.Uncurried@ effect wrapper - -- reduces to — @(\_ -> fn(a, …)) EffectRunArg@ — is just the call + -- Running the literal thunk that a saturated lifted @*.Uncurried@ effect + -- wrapper reduces to — @(\_ -> fn(a, …)) EffectRunArg@ — is just the call -- @fn(a, …)@: the uncurried @fn@ runs once it has every argument, so no -- thunk need be built and immediately forced (issue #198). This is the -- effect-side payoff of the lift — @fn(a, …)@ instead of diff --git a/lib/Language/PureScript/Backend/Lua/ForeignLift.hs b/lib/Language/PureScript/Backend/Lua/ForeignLift.hs index baea0cd1..11b2a9d2 100644 --- a/lib/Language/PureScript/Backend/Lua/ForeignLift.hs +++ b/lib/Language/PureScript/Backend/Lua/ForeignLift.hs @@ -27,10 +27,11 @@ The same machinery lifts the @run@ half of the @*.Uncurried@ wrappers @runSTFn2@ becomes @\\fn a b -> Abs _ (AppN fn [a, b])@ (the trailing effect thunk is a unary lambda with an unused parameter). Marked inline-always like every lifted accessor, a saturated call site collapses -to a single n-ary Lua call after beta reduction, and the effect thunk then -fuses away in statement position via magicDo — turning -@runSTFn2(pushImpl)(x)(arr)()@ from four calls and three closures into one -@pushImpl(x, arr)@. +to a single n-ary Lua call after beta reduction; the effect thunk — run +in statement position by magic-do's 'EffectRunArg' application — is then +shed at code generation ('Language.PureScript.Backend.Lua.fromIR'), +turning @runSTFn2(pushImpl)(x)(arr)()@ from four calls and three closures +into one @pushImpl(x, arr)@. = What lifts @@ -42,7 +43,8 @@ use: @function() … end@) → a unary 'Abs' with an unused parameter; * a saturated call @fn(a, b, …)@ of one or more arguments → the n-ary 'AppN' node (issue #198); a nullary @fn()@ has no 'AppN' and does not - lift; + lift, and a literal-lambda head called at any arity other than its + own declines (Note [n-ary application]); * @return@ / @if … then … else@ trees (an @elseif@ is a nested @if@ in the else branch) → 'IfThenElse', provided every branch returns a value (a branch that falls through to @nil@ does not lift); @@ -82,7 +84,7 @@ import Language.PureScript.Backend.IR.Types ( Exp , Grouping (Standalone) , PrimOp (..) - , RawExp (ForeignImport, ObjectProp) + , RawExp (AbsN, ForeignImport, ObjectProp) , abstraction , applicationN , eq @@ -306,9 +308,9 @@ liftLuaExp env bound = \case <$> liftBlock env (Set.insert param bound) body -- A zero-parameter function literal is the effect thunk of the -- @run{ST,Effect}FnN@ wrappers: @function() return fn(a, b) end@. It - -- lifts to a unary 'Abs' with an unused parameter — the shape magicDo - -- executes in statement position, so a saturated site fuses the thunk - -- away entirely (issue #198). + -- lifts to a unary 'Abs' with an unused parameter — the shape + -- magic-do runs in statement position and codegen then sheds, so a + -- saturated site fuses the thunk away entirely (issue #198). Function [] body → abstraction paramUnused <$> liftBlock env bound body -- A saturated call @fn(a, b, …)@ — the body of the @runFnN@ wrappers — @@ -318,7 +320,14 @@ liftLuaExp env bound = \case FunctionCall (_ann, fn) args → do fn' ← liftLuaExp env bound fn args' ← nonEmpty args >>= traverse (\(_ann', a) → liftLuaExp env bound a) - Just (applicationN fn' args') + -- A literal-lambda head (an inlined header local, or a parenthesized + -- function literal) must be called at exactly its own arity: any + -- other count would build an ill-formed 'AppN' (Note [n-ary + -- application]). Splitting the spine instead would change the + -- program — Lua drops surplus arguments — so a mismatch declines. + case fn' of + AbsN _ params _ | length params /= length args' → Nothing + _ → Just (applicationN fn' args') _ → Nothing {- | Translate a block that must be a pure return tree: a single @return@ diff --git a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs index c725af57..b28d7d69 100644 --- a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs +++ b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs @@ -128,8 +128,9 @@ spec = describe "Foreign lift (#178)" do it "lifts runSTFn2 to a thunk over an n-ary call" do -- The effectful wrapper: `\fn a b -> \() -> fn(a, b)`. The trailing -- `function()` thunk becomes a unary lambda with an unused parameter - -- (Abs paramUnused) — the exact shape magicDo already executes in - -- statement position, so the thunk and its three closures fuse away. + -- (Abs paramUnused) — the exact shape magic-do runs in statement + -- position and codegen then sheds, so the thunk and its three + -- closures fuse away. let src = "return { runSTFn2 = function(fn) return function(a) " <> "return function(b) return function() " @@ -164,12 +165,10 @@ spec = describe "Foreign lift (#178)" do -- `mkFn2 = \fn -> function(a, b) return fn(a)(b) end`: the inner -- multi-parameter function needs an n-ary AbsN (issue #24), so the -- wrapper stays an opaque foreign, not on this allowlist. - liftExport - ( source - "return { mkFn2 = function(fn) return function(a, b) return fn(a)(b) end end }" - ) - (Name "mkFn2") - `shouldSatisfy` isNothing + let src = + "return { mkFn2 = function(fn) " + <> "return function(a, b) return fn(a)(b) end end }" + liftExport (source src) (Name "mkFn2") `shouldSatisfy` isNothing describe "declines everything outside the subset" do it "declines a multi-parameter function (would misapply when curried)" do @@ -184,6 +183,17 @@ spec = describe "Foreign lift (#178)" do (Name "runFn0") `shouldSatisfy` isNothing + it "declines a literal-lambda call at a mismatched arity" do + -- `local k = function(x) return x end; f = \a -> k(a, a)`: legal + -- Lua (the surplus argument is dropped), but the header local + -- inlines to a literal unary 'Abs', and applying it to two + -- arguments would build an ill-formed 'AppN' (Note [n-ary + -- application]) — so the export declines instead. + let src = + "local k = function(x) return x end\n" + <> "return { f = function(a) return k(a, a) end }" + liftExport (source src) (Name "f") `shouldSatisfy` isNothing + it "declines a body with a table index" do liftExport (source "return { f = function(xs) return xs[1] end }") (Name "f") `shouldSatisfy` isNothing @@ -211,21 +221,28 @@ spec = describe "Foreign lift (#178)" do Set.member (qname "Data.Semigroup" "concatString") allowlist `shouldBe` True it "lists the *.Uncurried run wrappers (#198)" do - Set.member (qname "Data.Function.Uncurried" "runFn2") allowlist `shouldBe` True - Set.member (qname "Data.Function.Uncurried" "runFn10") allowlist `shouldBe` True + Set.member (qname "Data.Function.Uncurried" "runFn2") allowlist + `shouldBe` True + Set.member (qname "Data.Function.Uncurried" "runFn10") allowlist + `shouldBe` True Set.member (qname "Control.Monad.ST.Uncurried" "runSTFn1") allowlist `shouldBe` True - Set.member (qname "Effect.Uncurried" "runEffectFn2") allowlist `shouldBe` True + Set.member (qname "Effect.Uncurried" "runEffectFn2") allowlist + `shouldBe` True it "does not list the mk* wrappers (n-ary AbsN, #24) or opaque foreigns" do Set.member (qname "Data.Ord" "ordArrayImpl") allowlist `shouldBe` False Set.member (qname "Data.Semiring" "numAdd") allowlist `shouldBe` False - Set.member (qname "Data.Function.Uncurried" "mkFn2") allowlist `shouldBe` False - Set.member (qname "Effect.Uncurried" "mkEffectFn2") allowlist `shouldBe` False + Set.member (qname "Data.Function.Uncurried" "mkFn2") allowlist + `shouldBe` False + Set.member (qname "Effect.Uncurried" "mkEffectFn2") allowlist + `shouldBe` False -- runFn0/runFn1 are not lifted: runFn0 is a nullary call (no AppN), -- runFn1 has no foreign implementation (it is PureScript `id`). - Set.member (qname "Data.Function.Uncurried" "runFn0") allowlist `shouldBe` False - Set.member (qname "Data.Function.Uncurried" "runFn1") allowlist `shouldBe` False + Set.member (qname "Data.Function.Uncurried" "runFn0") allowlist + `shouldBe` False + Set.member (qname "Data.Function.Uncurried" "runFn1") allowlist + `shouldBe` False qname ∷ Text → Text → QName qname m n = QName (moduleNameFromString m) (Name n) From 9e4c0ae9234cde9ba8ecd121ad6f4cd05283b28e Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Sat, 11 Jul 2026 11:20:56 +0200 Subject: [PATCH 4/6] test(golden): link the real st fork FFI through the lifter (#198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runSTFn1..10 sit on the allowlist hard contract, but no CI path compiled the actual purescript-lua-st fork's Uncurried.lua through liftForeigns — a fork release reshaping it would break every downstream project while this repo stayed green. Add a runSTFn2 site to the UncurriedLift golden (st joins the test project's dependencies): the golden now pins the lifted direct n-ary call sumST(40, 2) and the eval oracle checks its result. --- .../Golden.UncurriedLift.Test/corefn.json | 2 +- .../Golden.UncurriedLift.Test/eval/golden.txt | 1 + .../Golden.UncurriedLift.Test/golden.ir | 258 +++++++++++++++++- .../Golden.UncurriedLift.Test/golden.lua | 78 +++++- test/ps/spago.lock | 1 + test/ps/spago.yaml | 1 + test/ps/src/Golden/UncurriedLift/Test.purs | 22 +- 7 files changed, 349 insertions(+), 14 deletions(-) diff --git a/test/ps/output/Golden.UncurriedLift.Test/corefn.json b/test/ps/output/Golden.UncurriedLift.Test/corefn.json index 24cd03e7..d464c367 100644 --- a/test/ps/output/Golden.UncurriedLift.Test/corefn.json +++ b/test/ps/output/Golden.UncurriedLift.Test/corefn.json @@ -1 +1 @@ -{"builtWith":"0.15.16","comments":[{"LineComment":" | Exercises the lifting of the @*.Uncurried@ run wrappers to direct"},{"LineComment":" | n-ary calls (issue #198)."},{"LineComment":" |"},{"LineComment":" | The pure @runFn2@/@runFn3@ sites must collapse to a single Lua call"},{"LineComment":" | (@add3(1, 2, 3)@), not the curried-onion @runFn3(add3)(1)(2)(3)@. The"},{"LineComment":" | effectful @runEffectFn2@ site sits in statement position, where magicDo"},{"LineComment":" | fuses the run wrapper's thunk away to a direct @logTwice(a, b)@ — one"},{"LineComment":" | call and no closures where the fallback paid four calls and three."}],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[22,25],"start":[22,24]}},"type":"Var","value":{"identifier":"mul","moduleName":["Data","Semiring"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[22,27],"start":[22,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"semiringInt","moduleName":["Data","Semiring"]}},"type":"App"},"identifier":"mul"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[26,8],"start":[26,3]}},"type":"Var","value":{"identifier":"discard","moduleName":["Control","Bind"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discardUnit","moduleName":["Control","Bind"]}},"type":"App"},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"bindEffect","moduleName":["Effect"]}},"type":"App"},"identifier":"discard"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[19,31],"start":[19,30]}},"type":"Var","value":{"identifier":"add","moduleName":["Data","Semiring"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"semiringInt","moduleName":["Data","Semiring"]}},"type":"App"},"identifier":"add"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[42,10],"start":[42,3]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Effect","Console"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"showInt","moduleName":["Data","Show"]}},"type":"App"},"identifier":"logShow"},{"annotation":{"meta":null,"sourceSpan":{"end":[21,24],"start":[21,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[22,13],"start":[22,8]}},"type":"Var","value":{"identifier":"mkFn2","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,14]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,14]}},"argument":"b","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"mul","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[22,23],"start":[22,22]}},"type":"Var","value":{"identifier":"a","sourcePos":[22,15]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[22,27],"start":[22,26]}},"type":"Var","value":{"identifier":"b","sourcePos":[22,17]}},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"mul2"},{"annotation":{"meta":null,"sourceSpan":{"end":[24,41],"start":[24,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[25,23],"start":[25,12]}},"type":"Var","value":{"identifier":"mkEffectFn2","moduleName":["Effect","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[25,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[25,24]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[25,24]}},"argument":"b","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[26,6],"start":[26,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,7]}},"type":"Var","value":{"identifier":"a","sourcePos":[25,25]}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,8],"start":[26,3]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[27,6],"start":[27,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[27,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[27,8],"start":[27,7]}},"type":"Var","value":{"identifier":"b","sourcePos":[25,27]}},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"logTwice"},{"annotation":{"meta":null,"sourceSpan":{"end":[18,28],"start":[18,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[19,13],"start":[19,8]}},"type":"Var","value":{"identifier":"mkFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,14]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,14]}},"argument":"b","body":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,14]}},"argument":"c","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"add","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"add","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,25],"start":[19,24]}},"type":"Var","value":{"identifier":"a","sourcePos":[19,15]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,29],"start":[19,28]}},"type":"Var","value":{"identifier":"b","sourcePos":[19,17]}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[19,33],"start":[19,32]}},"type":"Var","value":{"identifier":"c","sourcePos":[19,19]}},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"add3"},{"annotation":{"meta":null,"sourceSpan":{"end":[34,30],"start":[34,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[35,25],"start":[35,19]}},"type":"Var","value":{"identifier":"runFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[35,30],"start":[35,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[35,30],"start":[35,26]}},"type":"Var","value":{"identifier":"add3","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[35,32],"start":[35,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[35,32],"start":[35,31]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[35,34],"start":[35,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[35,34],"start":[35,33]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"App"},"identifier":"addOnePlusTwoTo"},{"annotation":{"meta":null,"sourceSpan":{"end":[37,20],"start":[37,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[41,15],"start":[41,3]}},"type":"Var","value":{"identifier":"runEffectFn2","moduleName":["Effect","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[41,24],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,24],"start":[41,16]}},"type":"Var","value":{"identifier":"logTwice","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[41,32],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,32],"start":[41,25]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"hello"}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,33]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"world"}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[41,40],"start":[41,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[42,18],"start":[42,12]}},"type":"Var","value":{"identifier":"runFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[42,23],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,23],"start":[42,19]}},"type":"Var","value":{"identifier":"add3","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,25],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,25],"start":[42,24]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,27],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,27],"start":[42,26]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,29],"start":[42,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,29],"start":[42,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":3}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[42,30],"start":[42,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[43,18],"start":[43,12]}},"type":"Var","value":{"identifier":"runFn2","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[43,23],"start":[43,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,23],"start":[43,19]}},"type":"Var","value":{"identifier":"mul2","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[43,25],"start":[43,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,25],"start":[43,24]}},"type":"Literal","value":{"literalType":"IntLiteral","value":4}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[43,27],"start":[43,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,27],"start":[43,26]}},"type":"Literal","value":{"literalType":"IntLiteral","value":5}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[43,28],"start":[43,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[44,27],"start":[44,12]}},"type":"Var","value":{"identifier":"addOnePlusTwoTo","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[44,31],"start":[44,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[44,31],"start":[44,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":100}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[44,32],"start":[44,3]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[45,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[45,27],"start":[45,12]}},"type":"Var","value":{"identifier":"addOnePlusTwoTo","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[45,31],"start":[45,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[45,31],"start":[45,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":200}},"type":"App"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"identifier":"main"}],"exports":["add3","mul2","logTwice","addOnePlusTwoTo","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Control","Bind"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Data","Function","Uncurried"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Data","Semiring"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Data","Show"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Effect"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Effect","Console"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Effect","Uncurried"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Golden","UncurriedLift","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[11,15],"start":[11,1]}},"moduleName":["Prelude"]},{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[9,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","UncurriedLift","Test"],"modulePath":"src/Golden/UncurriedLift/Test.purs","reExports":{},"sourceSpan":{"end":[45,32],"start":[9,1]}} \ No newline at end of file +{"builtWith":"0.15.16","comments":[{"LineComment":" | Exercises the lifting of the @*.Uncurried@ run wrappers to direct"},{"LineComment":" | n-ary calls (issue #198)."},{"LineComment":" |"},{"LineComment":" | The pure @runFn2@/@runFn3@ sites must collapse to a single Lua call"},{"LineComment":" | (@add3(1, 2, 3)@), not the curried-onion @runFn3(add3)(1)(2)(3)@. The"},{"LineComment":" | effectful @runEffectFn2@ site sits in statement position, where the"},{"LineComment":" | run wrapper's thunk (run by magic-do, shed by codegen) fuses away to"},{"LineComment":" | a direct @logTwice(a, b)@ — one call and no closures where the"},{"LineComment":" | fallback paid four calls and three."},{"LineComment":" |"},{"LineComment":" | The @runSTFn2@ site links @Control.Monad.ST.Uncurried@'s real fork"},{"LineComment":" | FFI through the lifter, so a fork release that reshapes it trips the"},{"LineComment":" | allowlist hard contract here instead of only downstream."}],"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[37,29],"start":[37,25]}},"type":"Var","value":{"identifier":"pure","moduleName":["Control","Applicative"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[37,37],"start":[37,25]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"applicativeST","moduleName":["Control","Monad","ST","Internal"]}},"type":"App"},"identifier":"pure"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[37,34],"start":[37,33]}},"type":"Var","value":{"identifier":"add","moduleName":["Data","Semiring"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[37,36],"start":[37,31]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"semiringInt","moduleName":["Data","Semiring"]}},"type":"App"},"identifier":"add"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[29,25],"start":[29,24]}},"type":"Var","value":{"identifier":"mul","moduleName":["Data","Semiring"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[29,27],"start":[29,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"semiringInt","moduleName":["Data","Semiring"]}},"type":"App"},"identifier":"mul"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[33,8],"start":[33,3]}},"type":"Var","value":{"identifier":"discard","moduleName":["Control","Bind"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[33,8],"start":[33,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discardUnit","moduleName":["Control","Bind"]}},"type":"App"},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[33,8],"start":[33,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"bindEffect","moduleName":["Effect"]}},"type":"App"},"identifier":"discard"},{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[53,10],"start":[53,3]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Effect","Console"]}},"annotation":{"meta":{"metaType":"IsSyntheticApp"},"sourceSpan":{"end":[53,30],"start":[53,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"showInt","moduleName":["Data","Show"]}},"type":"App"},"identifier":"logShow"},{"annotation":{"meta":null,"sourceSpan":{"end":[36,39],"start":[36,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[37,16],"start":[37,9]}},"type":"Var","value":{"identifier":"mkSTFn2","moduleName":["Control","Monad","ST","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[37,37],"start":[37,9]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[37,37],"start":[37,17]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[37,37],"start":[37,17]}},"argument":"b","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"pure","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[37,37],"start":[37,25]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"add","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[37,36],"start":[37,31]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[37,32],"start":[37,31]}},"type":"Var","value":{"identifier":"a","sourcePos":[37,18]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[37,36],"start":[37,31]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[37,36],"start":[37,35]}},"type":"Var","value":{"identifier":"b","sourcePos":[37,20]}},"type":"App"},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"sumST"},{"annotation":{"meta":null,"sourceSpan":{"end":[28,24],"start":[28,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[29,13],"start":[29,8]}},"type":"Var","value":{"identifier":"mkFn2","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[29,27],"start":[29,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[29,27],"start":[29,14]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[29,27],"start":[29,14]}},"argument":"b","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"mul","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[29,27],"start":[29,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[29,23],"start":[29,22]}},"type":"Var","value":{"identifier":"a","sourcePos":[29,15]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[29,27],"start":[29,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[29,27],"start":[29,26]}},"type":"Var","value":{"identifier":"b","sourcePos":[29,17]}},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"mul2"},{"annotation":{"meta":null,"sourceSpan":{"end":[31,41],"start":[31,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[32,23],"start":[32,12]}},"type":"Var","value":{"identifier":"mkEffectFn2","moduleName":["Effect","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[34,8],"start":[32,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[34,8],"start":[32,24]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[34,8],"start":[32,24]}},"argument":"b","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[33,8],"start":[33,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[33,6],"start":[33,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[33,8],"start":[33,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[33,8],"start":[33,7]}},"type":"Var","value":{"identifier":"a","sourcePos":[32,25]}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[33,8],"start":[33,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[33,8],"start":[33,3]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[34,6],"start":[34,3]}},"type":"Var","value":{"identifier":"log","moduleName":["Effect","Console"]}},"annotation":{"meta":null,"sourceSpan":{"end":[34,8],"start":[34,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[34,8],"start":[34,7]}},"type":"Var","value":{"identifier":"b","sourcePos":[32,27]}},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"logTwice"},{"annotation":{"meta":null,"sourceSpan":{"end":[25,28],"start":[25,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[26,13],"start":[26,8]}},"type":"Var","value":{"identifier":"mkFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,14]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,14]}},"argument":"b","body":{"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,14]}},"argument":"c","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"add","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,24]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"add","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,25],"start":[26,24]}},"type":"Var","value":{"identifier":"a","sourcePos":[26,15]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,29],"start":[26,28]}},"type":"Var","value":{"identifier":"b","sourcePos":[26,17]}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,24]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,32]}},"type":"Var","value":{"identifier":"c","sourcePos":[26,19]}},"type":"App"},"type":"Abs"},"type":"Abs"},"type":"Abs"},"type":"App"},"identifier":"add3"},{"annotation":{"meta":null,"sourceSpan":{"end":[44,30],"start":[44,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[45,25],"start":[45,19]}},"type":"Var","value":{"identifier":"runFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[45,30],"start":[45,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[45,30],"start":[45,26]}},"type":"Var","value":{"identifier":"add3","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[45,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[45,32],"start":[45,31]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[45,34],"start":[45,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[45,34],"start":[45,33]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"App"},"identifier":"addOnePlusTwoTo"},{"annotation":{"meta":null,"sourceSpan":{"end":[47,20],"start":[47,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[52,40],"start":[52,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[52,15],"start":[52,3]}},"type":"Var","value":{"identifier":"runEffectFn2","moduleName":["Effect","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[52,24],"start":[52,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[52,24],"start":[52,16]}},"type":"Var","value":{"identifier":"logTwice","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[52,32],"start":[52,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[52,32],"start":[52,25]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"hello"}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[52,40],"start":[52,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[52,40],"start":[52,33]}},"type":"Literal","value":{"literalType":"StringLiteral","value":"world"}},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[52,40],"start":[52,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[52,40],"start":[52,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[53,30],"start":[53,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[53,30],"start":[53,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[53,18],"start":[53,12]}},"type":"Var","value":{"identifier":"runFn3","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[53,23],"start":[53,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[53,23],"start":[53,19]}},"type":"Var","value":{"identifier":"add3","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[53,25],"start":[53,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[53,25],"start":[53,24]}},"type":"Literal","value":{"literalType":"IntLiteral","value":1}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[53,27],"start":[53,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[53,27],"start":[53,26]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[53,29],"start":[53,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[53,29],"start":[53,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":3}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[53,30],"start":[53,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[53,30],"start":[53,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[54,28],"start":[54,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[54,28],"start":[54,3]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[54,18],"start":[54,12]}},"type":"Var","value":{"identifier":"runFn2","moduleName":["Data","Function","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[54,23],"start":[54,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[54,23],"start":[54,19]}},"type":"Var","value":{"identifier":"mul2","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[54,25],"start":[54,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[54,25],"start":[54,24]}},"type":"Literal","value":{"literalType":"IntLiteral","value":4}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[54,27],"start":[54,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[54,27],"start":[54,26]}},"type":"Literal","value":{"literalType":"IntLiteral","value":5}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[54,28],"start":[54,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[54,28],"start":[54,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[55,32],"start":[55,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[55,32],"start":[55,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[55,27],"start":[55,12]}},"type":"Var","value":{"identifier":"addOnePlusTwoTo","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[55,31],"start":[55,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[55,31],"start":[55,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":100}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[55,32],"start":[55,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[55,32],"start":[55,3]}},"argument":"$__unused","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"discard","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[56,32],"start":[56,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[56,32],"start":[56,3]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[56,27],"start":[56,12]}},"type":"Var","value":{"identifier":"addOnePlusTwoTo","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[56,31],"start":[56,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[56,31],"start":[56,28]}},"type":"Literal","value":{"literalType":"IntLiteral","value":200}},"type":"App"},"type":"App"},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[56,32],"start":[56,3]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[56,32],"start":[56,3]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"type":"Var","value":{"identifier":"logShow","moduleName":["Golden","UncurriedLift","Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[57,3]}},"argument":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[57,18],"start":[57,12]}},"type":"Var","value":{"identifier":"run","moduleName":["Control","Monad","ST","Internal"]}},"annotation":{"meta":null,"sourceSpan":{"end":[57,40],"start":[57,12]}},"argument":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[57,28],"start":[57,20]}},"type":"Var","value":{"identifier":"runSTFn2","moduleName":["Control","Monad","ST","Uncurried"]}},"annotation":{"meta":null,"sourceSpan":{"end":[57,34],"start":[57,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[57,34],"start":[57,29]}},"type":"Var","value":{"identifier":"sumST","moduleName":["Golden","UncurriedLift","Test"]}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[57,37],"start":[57,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[57,37],"start":[57,35]}},"type":"Literal","value":{"literalType":"IntLiteral","value":40}},"type":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[57,39],"start":[57,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[57,39],"start":[57,38]}},"type":"Literal","value":{"literalType":"IntLiteral","value":2}},"type":"App"},"type":"App"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"type":"Abs"},"type":"App"},"identifier":"main"}],"exports":["add3","mul2","logTwice","sumST","addOnePlusTwoTo","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Control","Applicative"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Control","Bind"]},{"annotation":{"meta":null,"sourceSpan":{"end":[18,30],"start":[18,1]}},"moduleName":["Control","Monad","ST"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Control","Monad","ST","Internal"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Control","Monad","ST","Uncurried"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Data","Function","Uncurried"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Data","Semiring"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Data","Show"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Effect"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Effect","Console"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Effect","Uncurried"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Golden","UncurriedLift","Test"]},{"annotation":{"meta":null,"sourceSpan":{"end":[16,15],"start":[16,1]}},"moduleName":["Prelude"]},{"annotation":{"meta":null,"sourceSpan":{"end":[57,41],"start":[14,1]}},"moduleName":["Prim"]}],"moduleName":["Golden","UncurriedLift","Test"],"modulePath":"src/Golden/UncurriedLift/Test.purs","reExports":{},"sourceSpan":{"end":[57,41],"start":[14,1]}} \ No newline at end of file diff --git a/test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt b/test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt index 528a2d35..461e2a39 100644 --- a/test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt +++ b/test/ps/output/Golden.UncurriedLift.Test/eval/golden.txt @@ -4,3 +4,4 @@ world 20 103 203 +42 diff --git a/test/ps/output/Golden.UncurriedLift.Test/golden.ir b/test/ps/output/Golden.UncurriedLift.Test/golden.ir index 13348de2..4afdf03d 100644 --- a/test/ps/output/Golden.UncurriedLift.Test/golden.ir +++ b/test/ps/output/Golden.UncurriedLift.Test/golden.ir @@ -7,6 +7,23 @@ UberModule ( ModuleName "Data.Show" ) ".spago/p/prelude/26c058c2a053cf4dd7240f0d822ec096c0fecbe1/src/Data/Show.purs" [ ( Nothing, Name "showIntImpl" ) ] ), Standalone + ( QName + { qnameModuleName = ModuleName "Control.Monad.ST.Internal", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Control.Monad.ST.Internal" ) ".spago/p/st/6d41fd264a05b9a089e79322b22b906597ea7c36/src/Control/Monad/ST/Internal.purs" + [ + ( Nothing, Name "map_" ), + ( Nothing, Name "pure_" ), + ( Nothing, Name "bind_" ), + ( Nothing, Name "run" ) + ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Control.Monad.ST.Uncurried", qnameName = Name "foreign" + }, ForeignImport Nothing + ( ModuleName "Control.Monad.ST.Uncurried" ) ".spago/p/st/6d41fd264a05b9a089e79322b22b906597ea7c36/src/Control/Monad/ST/Uncurried.purs" + [ ( Nothing, Name "mkSTFn2" ) ] + ), Standalone ( QName { qnameModuleName = ModuleName "Data.Function.Uncurried", qnameName = Name "foreign" }, ForeignImport Nothing @@ -24,6 +41,200 @@ UberModule }, ForeignImport Nothing ( ModuleName "Effect.Uncurried" ) ".spago/p/effect/82bac3dff904fa34534c4f5b9deeb5da359471c8/src/Effect/Uncurried.purs" [ ( Nothing, Name "mkEffectFn2" ) ] + ), RecursiveGroup + ( + ( QName + { qnameModuleName = ModuleName "Control.Monad.ST.Internal", qnameName = Name "monadST" + }, LiteralObject Nothing + [ + ( PropName "Applicative0", AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "applicativeST" ) ) + ) + ), + ( PropName "Bind1", AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "bindST" ) ) + ) + ) + ] + ) :| + [ + ( QName + { qnameModuleName = ModuleName "Control.Monad.ST.Internal", qnameName = Name "bindST" + }, LiteralObject Nothing + [ + ( PropName "bind", ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "foreign" ) ) + ) + ( PropName "bind_" ) + ), + ( PropName "Apply0", AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "Lazy_applyST" ) ) + ) + ( LiteralInt Nothing 0 :| [] ) + ) + ) + ] + ), + ( QName + { qnameModuleName = ModuleName "Control.Monad.ST.Internal", qnameName = Name "applicativeST" + }, LiteralObject Nothing + [ + ( PropName "pure", ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "foreign" ) ) + ) + ( PropName "pure_" ) + ), + ( PropName "Apply0", AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "Lazy_applyST" ) ) + ) + ( LiteralInt Nothing 0 :| [] ) + ) + ) + ] + ), + ( QName + { qnameModuleName = ModuleName "Control.Monad.ST.Internal", qnameName = Name "Lazy_applyST" + }, AppN Nothing + ( AppN Nothing + ( Ref Nothing ( Local ( Name "PSLUA_runtime_lazy" ) ) ) + ( LiteralString Nothing "applyST" :| [] ) + ) + ( AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( LiteralObject Nothing + [ + ( PropName "apply", Let Nothing + ( Standalone + ( Nothing, Name "bind$604", ObjectProp Nothing + ( AppN Nothing + ( ObjectProp Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Control.Monad.ST.Internal" ) + ( Name "monadST" ) + ) + ) + ( PropName "Bind1" ) + ) + ( Ref Nothing + ( Imported ( ModuleName "Prim" ) ( Name "undefined" ) ) :| [] + ) + ) + ( PropName "bind" ) + ) :| [] + ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "f$605" ) :| [] ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "a$606" ) :| [] ) + ( AppN Nothing + ( AppN Nothing + ( Ref Nothing ( Local ( Name "bind$604" ) ) ) + ( Ref Nothing ( Local ( Name "f$605" ) ) :| [] ) + ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "f'$607" ) :| [] ) + ( AppN Nothing + ( AppN Nothing + ( Ref Nothing ( Local ( Name "bind$604" ) ) ) + ( Ref Nothing ( Local ( Name "a$606" ) ) :| [] ) + ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "a'$608" ) :| [] ) + ( AppN Nothing + ( ObjectProp Nothing + ( AppN Nothing + ( ObjectProp Nothing + ( Ref Nothing + ( Imported + ( ModuleName "Control.Monad.ST.Internal" ) + ( Name "monadST" ) + ) + ) + ( PropName "Applicative0" ) + ) + ( Ref Nothing + ( Imported + ( ModuleName "Prim" ) + ( Name "undefined" ) + ) :| [] + ) + ) + ( PropName "pure" ) + ) + ( AppN Nothing + ( Ref Nothing ( Local ( Name "f'$607" ) ) ) + ( Ref Nothing ( Local ( Name "a'$608" ) ) :| [] ) :| [] + ) + ) :| [] + ) + ) :| [] + ) + ) + ) + ) + ), + ( PropName "Functor0", AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( LiteralObject Nothing + [ + ( PropName "map", ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported + ( ModuleName "Control.Monad.ST.Internal" ) + ( Name "foreign" ) + ) + ) + ( PropName "map_" ) + ) + ] + ) + ) + ] + ) :| [] + ) + ) + ] + ), Standalone + ( QName + { qnameModuleName = ModuleName "Golden.UncurriedLift.Test", qnameName = Name "sumST" + }, AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Uncurried" ) ( Name "foreign" ) ) + ) + ( PropName "mkSTFn2" ) + ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "a" ) :| [] ) + ( AbsN Nothing + ( ParamNamed Nothing ( Name "b" ) :| [] ) + ( AppN Nothing + ( ObjectProp Nothing + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "applicativeST" ) ) + ) + ( PropName "pure" ) + ) + ( PrimBinOp Nothing PrimAdd + ( Ref Nothing ( Local ( Name "a" ) ) ) + ( Ref Nothing ( Local ( Name "b" ) ) ) :| [] + ) + ) + ) :| [] + ) ), Standalone ( QName { qnameModuleName = ModuleName "Golden.UncurriedLift.Test", qnameName = Name "mul2" @@ -115,11 +326,11 @@ UberModule ( QName { qnameModuleName = ModuleName "Golden.UncurriedLift.Test", qnameName = Name "addOnePlusTwoTo" }, AbsN Nothing - ( ParamNamed Nothing ( Name "c$314" ) :| [] ) + ( ParamNamed Nothing ( Name "c$547" ) :| [] ) ( AppN Nothing ( Ref Nothing ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) ) ( LiteralInt Nothing 1 :| - [ LiteralInt Nothing 2, Ref Nothing ( Local ( Name "c$314" ) ) ] + [ LiteralInt Nothing 2, Ref Nothing ( Local ( Name "c$547" ) ) ] ) ) ) @@ -134,6 +345,9 @@ UberModule ( Name "logTwice", Ref Nothing ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "logTwice" ) ) ), + ( Name "sumST", Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "sumST" ) ) + ), ( Name "addOnePlusTwoTo", Ref Nothing ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "addOnePlusTwoTo" ) ) ), @@ -220,6 +434,29 @@ UberModule ) ) ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) + ), Standalone + ( Nothing, Name "_", AppN Nothing + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Effect.Console" ) ( Name "foreign" ) ) ) + ( PropName "log" ) + ) + ( AppN Nothing + ( ObjectProp ( Just Always ) + ( Ref Nothing ( Imported ( ModuleName "Data.Show" ) ( Name "foreign" ) ) ) + ( PropName "showIntImpl" ) + ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) + ) + ( LiteralInt Nothing 1 :| + [ LiteralInt Nothing 2, LiteralInt Nothing 200 ] + ) :| [] + ) :| [] + ) + ) + ( Ref Nothing ( Imported ( ModuleName "Prim" ) ( Name "$magicDoRun" ) ) :| [] ) ) ] ) @@ -235,10 +472,21 @@ UberModule ( PropName "showIntImpl" ) ) ( AppN Nothing - ( Ref Nothing - ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "add3" ) ) + ( ObjectProp ( Just Always ) + ( Ref Nothing + ( Imported ( ModuleName "Control.Monad.ST.Internal" ) ( Name "foreign" ) ) + ) + ( PropName "run" ) ) - ( LiteralInt Nothing 1 :| [ LiteralInt Nothing 2, LiteralInt Nothing 200 ] ) :| [] + ( AbsN Nothing + ( ParamUnused Nothing :| [] ) + ( AppN Nothing + ( Ref Nothing + ( Imported ( ModuleName "Golden.UncurriedLift.Test" ) ( Name "sumST" ) ) + ) + ( LiteralInt Nothing 40 :| [ LiteralInt Nothing 2 ] ) + ) :| [] + ) :| [] ) :| [] ) ) diff --git a/test/ps/output/Golden.UncurriedLift.Test/golden.lua b/test/ps/output/Golden.UncurriedLift.Test/golden.lua index 6b2432e2..276e6c7e 100644 --- a/test/ps/output/Golden.UncurriedLift.Test/golden.lua +++ b/test/ps/output/Golden.UncurriedLift.Test/golden.lua @@ -1,5 +1,36 @@ +local function PSLUA_runtime_lazy(name) + return function(init) + local state = 0 + local val = nil + return function() + if state == 2 then + return val + elseif state == 1 then + return error(name .. " was needed before it finished initializing") + else + state = 1 + val = init() + state = 2 + return val + end + end + end +end local M = {} M.Data_Show_foreign = { showIntImpl = function(n) return tostring(n) end } +M.Control_Monad_ST_Internal_foreign = { + map_ = function(f) + return function(a) return function() return f(a()) end end + end, + pure_ = function(a) return function() return a end end, + bind_ = function(a) + return function(f) return function() return f(a())() end end + end, + run = function(f) return f() end +} +M.Control_Monad_ST_Uncurried_foreign = { + mkSTFn2 = function(fn) return function(a, b) return fn(a)(b)() end end +} M.Data_Function_Uncurried_foreign = { mkFn2 = function(fn) return function(a, b) return fn(a)(b) end end, mkFn3 = function(fn) return function(a, b, c) return fn(a)(b)(c) end end @@ -10,6 +41,44 @@ M.Effect_Console_foreign = { M.Effect_Uncurried_foreign = { mkEffectFn2 = function(fn) return function(a, b) return fn(a)(b)() end end } +M.Control_Monad_ST_Internal_monadST = { + Applicative0 = function() + return M.Control_Monad_ST_Internal_applicativeST + end, + Bind1 = function() return M.Control_Monad_ST_Internal_bindST end +} +M.Control_Monad_ST_Internal_bindST = { + bind = M.Control_Monad_ST_Internal_foreign.bind_, + Apply0 = function() return M.Control_Monad_ST_Internal_Lazy_applyST(0) end +} +M.Control_Monad_ST_Internal_applicativeST = { + pure = M.Control_Monad_ST_Internal_foreign.pure_, + Apply0 = function() return M.Control_Monad_ST_Internal_Lazy_applyST(0) end +} +M.Control_Monad_ST_Internal_Lazy_applyST = PSLUA_runtime_lazy("applyST")(function( ) + return { + apply = (function() + local bind_S_604 = (M.Control_Monad_ST_Internal_monadST.Bind1()).bind + return function(f_S_605) + return function(a_S_606) + return bind_S_604(f_S_605)(function(fPrime_S_607) + return bind_S_604(a_S_606)(function(aPrime_S_608) + return (M.Control_Monad_ST_Internal_monadST.Applicative0()).pure(fPrime_S_607(aPrime_S_608)) + end) + end) + end + end + end)(), + Functor0 = function() + return { map = M.Control_Monad_ST_Internal_foreign.map_ } + end + } +end) +M.Golden_UncurriedLift_Test_sumST = M.Control_Monad_ST_Uncurried_foreign.mkSTFn2(function( a ) + return function(b) + return M.Control_Monad_ST_Internal_applicativeST.pure(a + b) + end +end) M.Golden_UncurriedLift_Test_mul2 = M.Data_Function_Uncurried_foreign.mkFn2(function( a ) return function(b) return a * b end end) @@ -25,8 +94,8 @@ end) M.Golden_UncurriedLift_Test_add3 = M.Data_Function_Uncurried_foreign.mkFn3(function( a ) return function(b) return function(c) return a + b + c end end end) -M.Golden_UncurriedLift_Test_addOnePlusTwoTo = function(c_S_314) - return M.Golden_UncurriedLift_Test_add3(1, 2, c_S_314) +M.Golden_UncurriedLift_Test_addOnePlusTwoTo = function(c_S_547) + return M.Golden_UncurriedLift_Test_add3(1, 2, c_S_547) end return (function() local Data_Show_foreign, Effect_Console_foreign, Golden_UncurriedLift_Test_add3 = M.Data_Show_foreign, M.Effect_Console_foreign, M.Golden_UncurriedLift_Test_add3 @@ -34,5 +103,8 @@ return (function() local _ = Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(Golden_UncurriedLift_Test_add3(1, 2, 3)))() local _ = Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(M.Golden_UncurriedLift_Test_mul2(4, 5)))() local _ = Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(Golden_UncurriedLift_Test_add3(1, 2, 100)))() - return Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(Golden_UncurriedLift_Test_add3(1, 2, 200)))() + local _ = Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(Golden_UncurriedLift_Test_add3(1, 2, 200)))() + return Effect_Console_foreign.log(Data_Show_foreign.showIntImpl(M.Control_Monad_ST_Internal_foreign.run(function( ) + return M.Golden_UncurriedLift_Test_sumST(40, 2) + end)))() end)() diff --git a/test/ps/spago.lock b/test/ps/spago.lock index f002ac1e..a0c5191a 100644 --- a/test/ps/spago.lock +++ b/test/ps/spago.lock @@ -17,6 +17,7 @@ "partial", "prelude", "profunctor", + "st", "strings", "tailrec", "transformers", diff --git a/test/ps/spago.yaml b/test/ps/spago.yaml index 27ade0a4..210dfc1a 100644 --- a/test/ps/spago.yaml +++ b/test/ps/spago.yaml @@ -22,6 +22,7 @@ package: - partial - prelude - profunctor + - st - strings - tailrec - transformers diff --git a/test/ps/src/Golden/UncurriedLift/Test.purs b/test/ps/src/Golden/UncurriedLift/Test.purs index 63e1cb5c..e4e23227 100644 --- a/test/ps/src/Golden/UncurriedLift/Test.purs +++ b/test/ps/src/Golden/UncurriedLift/Test.purs @@ -3,13 +3,20 @@ -- | -- | The pure @runFn2@/@runFn3@ sites must collapse to a single Lua call -- | (@add3(1, 2, 3)@), not the curried-onion @runFn3(add3)(1)(2)(3)@. The --- | effectful @runEffectFn2@ site sits in statement position, where magicDo --- | fuses the run wrapper's thunk away to a direct @logTwice(a, b)@ — one --- | call and no closures where the fallback paid four calls and three. +-- | effectful @runEffectFn2@ site sits in statement position, where the +-- | run wrapper's thunk (run by magic-do, shed by codegen) fuses away to +-- | a direct @logTwice(a, b)@ — one call and no closures where the +-- | fallback paid four calls and three. +-- | +-- | The @runSTFn2@ site links @Control.Monad.ST.Uncurried@'s real fork +-- | FFI through the lifter, so a fork release that reshapes it trips the +-- | allowlist hard contract here instead of only downstream. module Golden.UncurriedLift.Test where import Prelude +import Control.Monad.ST as ST +import Control.Monad.ST.Uncurried (STFn2, mkSTFn2, runSTFn2) import Data.Function.Uncurried (Fn2, Fn3, mkFn2, mkFn3, runFn2, runFn3) import Effect (Effect) import Effect.Console (log, logShow) @@ -26,6 +33,9 @@ logTwice = mkEffectFn2 \a b -> do log a log b +sumST :: forall r. STFn2 Int Int r Int +sumST = mkSTFn2 \a b -> pure (a + b) + -- A partial application: `runFn3 add3 1 2` supplies only two of add3's -- three arguments, so this exported binding stays a function of the last — -- lifted to a direct n-ary `add3(1, 2, c)`, the wrapper's curried-fallback @@ -36,10 +46,12 @@ addOnePlusTwoTo = runFn3 add3 1 2 main :: Effect Unit main = do - -- A non-tail effect statement: magicDo fuses the run wrapper's thunk - -- away, so this becomes a direct `local _ = logTwice("hello", "world")`. + -- A non-tail effect statement: the run wrapper's thunk (run by + -- magic-do, shed by codegen) fuses away, so this becomes a direct + -- `local _ = logTwice("hello", "world")`. runEffectFn2 logTwice "hello" "world" -- hello / world logShow (runFn3 add3 1 2 3) -- 6 logShow (runFn2 mul2 4 5) -- 20 logShow (addOnePlusTwoTo 100) -- 103 logShow (addOnePlusTwoTo 200) -- 203 + logShow (ST.run (runSTFn2 sumST 40 2)) -- 42 From fbf1cdca025b8a92b1a26bea9af553effd2ccf81 Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Sat, 11 Jul 2026 11:30:21 +0200 Subject: [PATCH 5/6] docs: retarget the mk-wrapper references from #24 to #227 The comments pointing at the mk wrappers' missing n-ary AbsN lift cited #24, a closed issue that never covered mk-lifting. That work is now tracked by #227, so the allowlist comment, the spec test names, and the changelog fragment point there instead. Legitimate #24 references (the worker/wrapper uncurrying split itself) are untouched. --- .../20260710_131814_unisay_lift_uncurried_wrappers.md | 2 +- lib/Language/PureScript/Backend/Lua/ForeignLift.hs | 2 +- test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md b/changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md index 13dd341a..a1b8070b 100644 --- a/changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md +++ b/changelog.d/20260710_131814_unisay_lift_uncurried_wrappers.md @@ -10,7 +10,7 @@ site then beta-reduces to a single n-ary Lua call, so `runFn3 impl x y z` compiles to `impl(x, y, z)` rather than the two-closure curried onion; a partial application keeps the wrapper's curried fallback. The `mk` - counterparts need an n-ary `AbsN` (#24) and stay opaque. + counterparts need an n-ary `AbsN` (#227) and stay opaque. - An `Effect`/`ST` statement whose action is a lifted uncurried wrapper now sheds its final closure at code generation: the effect run of a literal thunk, `(\_ -> fn(a, …)) EffectRunArg`, lowers straight to the call `fn(a, …)` diff --git a/lib/Language/PureScript/Backend/Lua/ForeignLift.hs b/lib/Language/PureScript/Backend/Lua/ForeignLift.hs index 11b2a9d2..ba0f0199 100644 --- a/lib/Language/PureScript/Backend/Lua/ForeignLift.hs +++ b/lib/Language/PureScript/Backend/Lua/ForeignLift.hs @@ -153,7 +153,7 @@ allowlist = ) , ("Data.Semigroup", ["concatString"]) , -- The @run@ half of the uncurried FFI wrappers (issue #198). Their - -- @mk@ counterparts need an n-ary 'AbsN' (issue #24) and stay opaque; + -- @mk@ counterparts need an n-ary 'AbsN' (issue #227) and stay opaque; -- @runFn0@ is a nullary call with no 'AppN', @runFn1@ is PureScript -- @id@ with no foreign — both absent below. ("Data.Function.Uncurried", runWrappers "runFn" [2 .. 10]) diff --git a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs index b28d7d69..0697aaad 100644 --- a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs +++ b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs @@ -161,9 +161,9 @@ spec = describe "Foreign lift (#178)" do applicationN (refLocal fn) (refLocal a :| []) ) - it "declines the mk* wrappers (their inner function is n-ary, #24)" do + it "declines the mk* wrappers (their inner function is n-ary, #227)" do -- `mkFn2 = \fn -> function(a, b) return fn(a)(b) end`: the inner - -- multi-parameter function needs an n-ary AbsN (issue #24), so the + -- multi-parameter function needs an n-ary AbsN (issue #227), so the -- wrapper stays an opaque foreign, not on this allowlist. let src = "return { mkFn2 = function(fn) " @@ -230,7 +230,7 @@ spec = describe "Foreign lift (#178)" do Set.member (qname "Effect.Uncurried" "runEffectFn2") allowlist `shouldBe` True - it "does not list the mk* wrappers (n-ary AbsN, #24) or opaque foreigns" do + it "does not list the mk* wrappers (n-ary AbsN, #227) or opaque foreigns" do Set.member (qname "Data.Ord" "ordArrayImpl") allowlist `shouldBe` False Set.member (qname "Data.Semiring" "numAdd") allowlist `shouldBe` False Set.member (qname "Data.Function.Uncurried" "mkFn2") allowlist From a1bc7cc16bba5a3f0f5e5083b33137d01a500b03 Mon Sep 17 00:00:00 2001 From: Yura Lazarev Date: Sat, 11 Jul 2026 11:37:19 +0200 Subject: [PATCH 6/6] test(foreign-lift): drop the allowlist-membership assertions The membership tests restated the allowlist literal item by item, so any edit to the set required the same edit in the spec without any invariant being checked. The contract that matters (every listed export lifts against the real fork FFI) is exercised by the golden and bench links, which run liftForeigns over the actual package-set sources. --- .../Backend/Lua/ForeignLift/Spec.hs | 43 +------------------ 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs index 0697aaad..c9c05284 100644 --- a/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs +++ b/test/Language/PureScript/Backend/Lua/ForeignLift/Spec.hs @@ -1,11 +1,6 @@ module Language.PureScript.Backend.Lua.ForeignLift.Spec where -import Data.Set qualified as Set -import Language.PureScript.Backend.IR.Names - ( Name (..) - , QName (..) - , moduleNameFromString - ) +import Language.PureScript.Backend.IR.Names (Name (..)) import Language.PureScript.Backend.IR.Types ( PrimOp (..) , abstraction @@ -18,7 +13,7 @@ import Language.PureScript.Backend.IR.Types , primNot , refLocal ) -import Language.PureScript.Backend.Lua.ForeignLift (allowlist, liftExport) +import Language.PureScript.Backend.Lua.ForeignLift (liftExport) import Language.PureScript.Backend.Lua.Linker.Foreign ( Source , interpretForeignModule @@ -213,40 +208,6 @@ spec = describe "Foreign lift (#178)" do liftExport (source "return { a = function(x) return x end }") (Name "b") `shouldSatisfy` isNothing - describe "allowlist" do - it "lists the arithmetic/comparison/boolean/concat core" do - Set.member (qname "Data.Semiring" "intAdd") allowlist `shouldBe` True - Set.member (qname "Data.Ord" "ordIntImpl") allowlist `shouldBe` True - Set.member (qname "Data.Eq" "refEq") allowlist `shouldBe` True - Set.member (qname "Data.Semigroup" "concatString") allowlist `shouldBe` True - - it "lists the *.Uncurried run wrappers (#198)" do - Set.member (qname "Data.Function.Uncurried" "runFn2") allowlist - `shouldBe` True - Set.member (qname "Data.Function.Uncurried" "runFn10") allowlist - `shouldBe` True - Set.member (qname "Control.Monad.ST.Uncurried" "runSTFn1") allowlist - `shouldBe` True - Set.member (qname "Effect.Uncurried" "runEffectFn2") allowlist - `shouldBe` True - - it "does not list the mk* wrappers (n-ary AbsN, #227) or opaque foreigns" do - Set.member (qname "Data.Ord" "ordArrayImpl") allowlist `shouldBe` False - Set.member (qname "Data.Semiring" "numAdd") allowlist `shouldBe` False - Set.member (qname "Data.Function.Uncurried" "mkFn2") allowlist - `shouldBe` False - Set.member (qname "Effect.Uncurried" "mkEffectFn2") allowlist - `shouldBe` False - -- runFn0/runFn1 are not lifted: runFn0 is a nullary call (no AppN), - -- runFn1 has no foreign implementation (it is PureScript `id`). - Set.member (qname "Data.Function.Uncurried" "runFn0") allowlist - `shouldBe` False - Set.member (qname "Data.Function.Uncurried" "runFn1") allowlist - `shouldBe` False - -qname ∷ Text → Text → QName -qname m n = QName (moduleNameFromString m) (Name n) - {- | Parse a foreign-module source into a 'Source', failing the test with a clear message if it does not parse or interpret. -}