From 729928c93dfbcfb6b4833206afe3c2ba9f285635 Mon Sep 17 00:00:00 2001 From: Codex Date: Sun, 20 Sep 2026 11:58:59 +0800 Subject: [PATCH 1/9] Effect Analysis Prototype Co-authored-by: Flandia --- .../shared/src/main/scala/hkmc2/Config.scala | 5 + .../scala/hkmc2/codegen/EtaExpansion.scala | 4 +- .../codegen/flowAnalysis/EffectAnalysis.scala | 83 + .../codegen/flowAnalysis/FlowAnalysis.scala | 143 +- .../src/main/scala/hkmc2/semantics/Term.scala | 2 + .../test/mlscript/codegen/ConfigDirective.mls | 9 +- .../test/mlscript/dead-param-elim/todos.mls | 38 + .../src/test/mlscript/deforest/append.mls | 134 ++ .../src/test/mlscript/deforest/basic.mls | 148 ++ .../src/test/mlscript/deforest/clashes.mls | 113 ++ .../src/test/mlscript/deforest/cyclic.mls | 58 + .../test/mlscript/deforest/determinism.mls | 7 + .../src/test/mlscript/deforest/dropLast.mls | 112 ++ .../test/mlscript/deforest/erasedTypes.mls | 11 + .../mlscript/deforest/eta-expansion/basic.mls | 60 + .../deforest/eta-expansion/recursive.mls | 46 + .../src/test/mlscript/deforest/fusibility.mls | 252 ++++ .../src/test/mlscript/deforest/imperative.mls | 26 + .../mlscript/deforest/listComprehension.mls | 156 ++ .../src/test/mlscript/deforest/module.mls | 165 ++ .../test/mlscript/deforest/multiArgLists.mls | 24 + .../test/mlscript/deforest/nestedMatch.mls | 336 +++++ .../src/test/mlscript/deforest/recursive.mls | 1335 +++++++++++++++++ .../mlscript/deforest/relaxedPrograms.mls | 62 + .../deforest/selectionsInNestedMatch.mls | 69 + .../src/test/mlscript/deforest/simple.mls | 883 +++++++++++ .../test/mlscript/deforest/stratvarNaming.mls | 21 + .../src/test/mlscript/deforest/todos.mls | 79 +- .../src/test/mlscript/deforest/zipunzip.mls | 160 ++ .../test/mlscript/effect-analysis/Basic.mls | 315 ++++ .../test/mlscript/effect-analysis/Imports.mls | 74 + .../src/test/scala/hkmc2/MLsDiffMaker.scala | 1 + 32 files changed, 4899 insertions(+), 32 deletions(-) create mode 100644 hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala create mode 100644 hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls create mode 100644 hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls diff --git a/hkmc2/shared/src/main/scala/hkmc2/Config.scala b/hkmc2/shared/src/main/scala/hkmc2/Config.scala index a3cd035e58..8df78e5689 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/Config.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/Config.scala @@ -163,6 +163,7 @@ object Config: debugEta: Bool = false, debugDpe: Bool = false, debugDce: Bool = false, + logEffects: Bool = false, ): def effectiveDebugEta: Bool = debug || debugEta def effectiveDebugDpe: Bool = debug || debugDpe @@ -541,6 +542,7 @@ object ConfigParser: var debugEta = base.debugEta var debugDpe = base.debugDpe var debugDce = base.debugDce + var logEffects = base.logEffects args.foreach: case NamedArg("debug", value) => setFrom(value)(parseBool)(v => debug = v) @@ -560,6 +562,8 @@ object ConfigParser: setFrom(value)(parseBool)(v => debugDpe = v) case NamedArg("debugDce", value) => setFrom(value)(parseBool)(v => debugDce = v) + case NamedArg("logEffects", value) => + setFrom(value)(parseBool)(v => logEffects = v) case other => unsupported(passName, other) S(Config.FlowAnalysisConfig( @@ -572,6 +576,7 @@ object ConfigParser: debugEta, debugDpe, debugDce, + logEffects, )) case _ => expect(s"${passName}(...)")(tree) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala index cad92575d6..c254431d8d 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala @@ -91,7 +91,7 @@ class EtaExpansionSolver(val constraintSolver: FlowConstraintSolver, tl: TraceLo EtaTargets(a.paramCount, a.hasRestParam, a.prodFuns ++ b.prodFuns) go(S(mergedRes)) else Nil - case UnknownProd => Nil + case UnknownProd | UnsafeEta => Nil case _: Ctor => Nil end go @@ -101,7 +101,7 @@ class EtaExpansionSolver(val constraintSolver: FlowConstraintSolver, tl: TraceLo case _ => false then go(N) else Nil - case UnknownProd => Nil + case UnknownProd | UnsafeEta => Nil case _: Ctor => Nil end funResShape diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala new file mode 100644 index 0000000000..55ad9b33ab --- /dev/null +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala @@ -0,0 +1,83 @@ +package hkmc2 +package codegen +package flowAnalysis + +import hkmc2.semantics.* +import hkmc2.utils.*, shorthands.* +import utils.* + + +enum EffectSummary: + case Pure, UnsafeEta + + +case class EffectAnalysisResult( + latentEffects: Map[ConcreteId[FunId], EffectSummary], + callEffects: Map[ConcreteId[ResultId], EffectSummary], +) + + +object EffectAnalysis: + + + def summarize(effectVar: StratVar): EffectSummary = + if effectVar.lowerBounds.contains(UnsafeEta) + then EffectSummary.UnsafeEta + else EffectSummary.Pure + + def apply(solver: FlowConstraintSolver)(using tl: TraceLogger): EffectAnalysisResult = + given fState: FlowAnalysis.State = solver.fState + given eState: Elaborator.State = solver.eState + + + val result = EffectAnalysisResult( + solver.functionEffectVars.iterator.map((id, effect) => id -> summarize(effect)).toMap, + solver.callEffectVars.iterator.map((id, effect) => id -> summarize(effect)).toMap, + ) + + if tl.doTrace then logResult(result) + result + end apply + + private def logResult(result: EffectAnalysisResult)(using + tl: TraceLogger, + fState: FlowAnalysis.State, + eState: Elaborator.State, + ): Unit = + def showRefSite(resultId: ResultId): Str = + resultId.getReferredFun match + case Some(fun) => s"${fun.nme}@$resultId" + case None => s"${resultId.getResult}@$resultId" + + def showInstId(instId: InstantiationId): Str = + if instId.isEmpty then "" else instId.map(showRefSite).mkString(".") + + def showFunction(id: ConcreteId[FunId]): Str = + val name = id.exprId match + case (funSym: TermSymbol, whichParamList) => s"${funSym.nme}#$whichParamList" + case exprId: ResultId => s"lambda@$exprId" + s"function $name @ ${showInstId(id.instId)}" + + def showPath(path: Path): Str = path match + case Value.SimpleRef(sym) => sym.nme + case Value.MemberRef(_, disamb) => disamb.nme + case Select(_, name) => name.name + case _ => "" + + def showCall(id: ConcreteId[ResultId]): Str = + val call = id.exprId.getResult match + case Call(fun, _) => s"call ${showPath(fun)}@${id.exprId}" + case Instantiate(_, cls, _) => s"instantiate ${showPath(cls)}@${id.exprId}" + case other => s"call $other@${id.exprId}" + s"$call @ ${showInstId(id.instId)}" + + tl.log(">>> effect-analysis results >>>") + result.latentEffects.iterator.map: (id, effect) => + s"${showFunction(id)} -> $effect" + .toSeq.sorted.foreach(tl.log(_)) + result.callEffects.iterator.map: (id, effect) => + s"${showCall(id)} -> $effect" + .toSeq.sorted.foreach(tl.log(_)) + tl.log("<<< effect-analysis results <<<") + end logResult +end EffectAnalysis diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala index 6941682f6d..1fd443c9ad 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala @@ -16,6 +16,7 @@ object FlowAnalysis: object TraceScope: val NonAffineSyms = "flow-analysis/non-affine" val AccumulatorSym = "flow-analysis/accumulator" + val Effects = "flow-analysis/effects" class State(using val eState: Elaborator.State): val resultToResultId = new java.util.IdentityHashMap[Result, ResultId].asScala @@ -78,11 +79,22 @@ object FlowAnalysis: mono: Bool, nonAffineTracking: Bool, accumulatorTracking: Bool, + logEffects: Bool = true, )(using TraceLogger, Elaborator.State, Raise, SymbolPrinter) = given State = new State val pre = new FlowPreAnalyzer(pgrm) - val constrCol = new FlowConstraintsCollector(pre, mono, nonAffineTracking, accumulatorTracking) - new FlowConstraintSolver(constrCol) + val constrCol = new FlowConstraintsCollector( + pre, + mono, + nonAffineTracking, + accumulatorTracking, + ) + val solver = new FlowConstraintSolver(constrCol) + val tl = summon[TraceLogger] + // Inference is unconditional; logging must not affect optimization decisions. + if logEffects then tl.scoped(TraceScope.Effects): + if tl.doTrace then EffectAnalysis(solver) + solver def mkTraceLogger( cfg: Config.FlowAnalysisConfig, @@ -93,6 +105,7 @@ object FlowAnalysis: override def doTrace: Bool = scope match case S(TraceScope.NonAffineSyms) => cfg.logNonAffine case S(TraceScope.AccumulatorSym) => cfg.logAccumulator + case S(TraceScope.Effects) => cfg.debug || cfg.logEffects case _ => cfg.debug override def emitDbg(str: Str): Unit = @@ -232,7 +245,8 @@ class ProdFun( val params: Ls[ConsStrat], val restParam: Opt[ConsStrat], val res: ProdStrat, - val capturedVarUpperbound: StratVar + val capturedVarUpperbound: StratVar, + val effect: Opt[StratVar], ) extends ProdStrat with StratWithOrigin[FunId]: val dests = MutSet.empty[ConsFun | MarkerConsStrat] override def toString(): String = @@ -240,6 +254,9 @@ class ProdFun( case object UnknownProd extends MarkerProdStrat +/** The lower bound marker marking an effect variable as effect-raising. */ +case object UnsafeEta extends MarkerProdStrat + class Ctor( val exprId: ResultId, val instantiationId: Opt[InstantiationId] @@ -254,10 +271,11 @@ class Ctor( class ConsFun( val exprId: ResultId, - val instantiationId: Opt[InstantiationId] + val instantiationId: Opt[InstantiationId], )( val params: Ls[ProdStrat], - val res: ConsStrat + val res: ConsStrat, + val effect: Opt[StratVar], ) extends ConsStrat with StratWithOrigin[ResultId]: val srcs = MutSet.empty[ProdFun | MarkerProdStrat] override def toString(): String = @@ -742,7 +760,8 @@ class FlowConstraintsCollector( s"${funSym.nme}_res", fun.params, fun.body, - (fun.dSym, -1)) + (fun.dSym, -1), + fun.annotations) cc.constrain(funProdStrat, thisFunVar) if nonAffineTracking then for @@ -761,7 +780,7 @@ class FlowConstraintsCollector( globalCollector.givenIn: cc ?=> cc.constrain(preAnalyzer.res.primitiveStratVar, UnknownCons) cc.constrain(UnknownProd, preAnalyzer.res.primitiveStratVar) - processBlock(preAnalyzer.pgrm.main)(using cc, UnknownCons) + processBlock(preAnalyzer.pgrm.main)(using cc, UnknownCons, N) // this places non-affine constraints correctly: // - in mono mode there are no per-scc collectors, @@ -819,8 +838,10 @@ class FlowConstraintsCollector( p.params.map(duplicateConsStrat), p.restParam.map(duplicateConsStrat), duplicateProdStrat(p.res), - duplicateVarState(p.capturedVarUpperbound)) + duplicateVarState(p.capturedVarUpperbound), + p.effect.map(duplicateVarState)) case UnknownProd => UnknownProd + case UnsafeEta => UnsafeEta case c: Ctor => registerCtor( new Ctor(c.exprId, updateInstantiationId(c.instantiationId))( c.ctor, @@ -830,7 +851,8 @@ class FlowConstraintsCollector( case c: ConsFun => new ConsFun(c.exprId, updateInstantiationId(c.instantiationId))( c.params.map(duplicateProdStrat), - duplicateConsStrat(c.res)) + duplicateConsStrat(c.res), + c.effect.map(duplicateVarState)) case UnknownCons => UnknownCons case NonAffine => NonAffine case Accumulator => Accumulator @@ -856,7 +878,8 @@ class FlowConstraintsCollector( resName: String, params: Ls[ParamList], body: Block, - funLamId: FunId + funLamId: FunId, + annotations: Ls[Annot] )(using cc: ConstraintsCollector): ProdStrat = def paramListFunId(whichParamList: Int): FunId = funLamId match @@ -870,12 +893,21 @@ class FlowConstraintsCollector( case lamExprId: ResultId => preAnalyzer.res.capturedVars(lamExprId) case other => lastWords(s"unexpected funLamId shape: $other") val res = freshVar(resName, cc.forFun) + val effect = + if params.nonEmpty then + S(freshVar(s"effect_$funLamId", cc.forFun)) + else N params.foreach: _.restParam.foreach: p => generatedVars(p.sym).constrainOpaque val funValueStrat = params.zipWithIndex.foldRight[ProdStrat](res): case ((ps, whichParamList), acc) => val plFunId = paramListFunId(whichParamList) + // A declared curried function runs its body only at the final list. + // Earlier stages capture arguments; each needs its own, initially pure summary. + val stageEffect = + if whichParamList == params.size - 1 then effect + else effect.map(_ => freshVar(s"effect_$plFunId", cc.forFun)) val capUB = freshVar(s"cap_ub_$plFunId", cc.forFun) for v <- capturedSyms @@ -886,8 +918,11 @@ class FlowConstraintsCollector( ps.params.map(p => generatedVars(p.sym)), ps.restParam.map(p => generatedVars(p.sym)), acc, - capUB) - processBlock(body)(using cc, res) + capUB, + stageEffect) + // An explicit @pure annotation overrides the latent effect. Keep analyzing body + // calls, but do not let their effects flow into this trusted override. + processBlock(body)(using cc, res, if annotations.exists(_.isInstanceOf[Annot.Pure]) then N else effect) funValueStrat def processFunctionDefn(fun: FunDefn)(using cc: ConstraintsCollector): Unit = @@ -898,7 +933,8 @@ class FlowConstraintsCollector( s"${fun.dSym.nme}_res", fun.params, fun.body, - (fun.dSym, -1)) + (fun.dSym, -1), + fun.annotations) cc.constrain(funProdStrat, generatedVars(fun.dSym)) def processClsLikeDefn(cls: ClsLikeDefn)(using cc: ConstraintsCollector): Unit = @@ -908,21 +944,21 @@ class FlowConstraintsCollector( cls.methods.foreach: fun => generatedVars(fun.dSym).constrainOpaque fun.params.foreach(_.allParams.foreach(p => generatedVars(p.sym).constrainOpaque)) - processBlock(fun.body)(using cc, UnknownCons) - processBlock(cls.preCtor)(using cc, UnknownCons) - processBlock(cls.ctor)(using cc, UnknownCons) + processBlock(fun.body)(using cc, UnknownCons, N) + processBlock(cls.preCtor)(using cc, UnknownCons, N) + processBlock(cls.ctor)(using cc, UnknownCons, N) cls.companion.foreach: mod => mod.privateFields.foreach(sym => generatedVars(sym).constrainOpaque) mod.publicFields.foreach: (_, tsym) => generatedVars(tsym).constrainOpaque mod.methods.foreach: fun => processFunctionDefn(fun) - processBlock(mod.ctor)(using cc, UnknownCons) + processBlock(mod.ctor)(using cc, UnknownCons, N) - def constrainOpaqueResult(r: Result)(using cc: ConstraintsCollector): Unit = + def constrainOpaqueResult(r: Result)(using cc: ConstraintsCollector, currentEffect: Opt[StratVar]): Unit = cc.constrain(processResult(r), UnknownCons) - def processBlock(b: Block)(using cc: ConstraintsCollector, blkRes: ConsStrat): Unit = + def processBlock(b: Block)(using cc: ConstraintsCollector, blkRes: ConsStrat, currentEffect: Opt[StratVar]): Unit = val instId = cc.instId b match case Return(res) => cc.constrain(processResult(res), blkRes) @@ -975,18 +1011,46 @@ class FlowConstraintsCollector( case End(msg) => () case Unreachable(_) => () - def processResult(r: Result)(using cc: ConstraintsCollector): ProdStrat = + def processResult(r: Result)(using cc: ConstraintsCollector, currentEffect: Opt[StratVar]): ProdStrat = val instId = cc.instId - def handleCallLike(callExprId: ResultId, f: Path, args: List[Arg]): ProdStrat = - val fStrat = processResult(f) + def freshCallEffect(): StratVar = + val effect = freshVar("call_effect", cc.forFun) + // A call's effect contributes to the enclosing function's latent effect. + currentEffect.foreach: enclosingEffect => + cc.constrain(effect, enclosingEffect) + effect + def constrainConstructorEffect(result: Result): Unit = + val unsafeEta = result match + case call: Call => call.metadata.mayRaiseEffects + case _: Instantiate => true + case _ => false + // Constructor bodies are not modeled here; instantiation may have effects. + if unsafeEta then currentEffect.foreach(e => cc.constrain(UnsafeEta, e)) + def handleCallLike( + call: Call, + args: List[Arg], + opaqueTail: Bool, + ): ProdStrat = + val callExprId = call.uid + val fStrat = processResult(call.fun) val argsStrat = args.map(a => processResult(a.value)) if args.exists(_.spread.isDefined) then + // TODO: preserve callee-effect precision for spread calls without modeling their argument flow. + // Honor trusted call metadata; otherwise mark the caller without a separate call summary. + if call.metadata.mayRaiseEffects then + currentEffect.foreach(e => cc.constrain(UnsafeEta, e)) cc.constrain(fStrat, UnknownCons) argsStrat.foreach(arg => cc.constrain(arg, UnknownCons)) UnknownProd else val callRes = freshVar("call_res", cc.forFun) - cc.constrain(fStrat, new ConsFun(callExprId, instId)(argsStrat, callRes)) + val effect = freshCallEffect() + if opaqueTail then cc.constrain(UnsafeEta, effect) + cc.constrain(fStrat, new ConsFun(callExprId, instId)( + argsStrat, + callRes, + S(effect), + )) callRes r match case sel@TrackableSelect(from, field, owner) => @@ -997,6 +1061,7 @@ class FlowConstraintsCollector( new FieldSel(sel.uid, instId)(field, owner, selRes)) selRes case c@CtorProducer(ctor, args, selectedFrom) if args.forall(_.spread.isEmpty) => + constrainConstructorEffect(c) for qual <- selectedFrom do cc.constrain(processResult(qual), UnknownCons) val argsStrat = args.map: @@ -1020,30 +1085,32 @@ class FlowConstraintsCollector( case tupSize: Int => registerCtor(new Ctor(c.uid, instId)(tupSize, (0 until tupSize).zip(argsStrat).toList)) case c@CtorProducer(_, args, selectedFrom) => + constrainConstructorEffect(c) for qual <- selectedFrom do cc.constrain(processResult(qual), UnknownCons) args.foreach(arg => cc.constrain(processResult(arg.value), UnknownCons)) UnknownProd case c@Call(fun, argss) => argss match - case args :: Nil => handleCallLike(c.uid, fun, args) + case args :: Nil => handleCallLike(c, args, opaqueTail = false) case args :: rest => // For multi-arg-list calls, handle the first arg list normally for // dead-param-elim, then constrain subsequent arg lists opaquely. // We cannot reuse c.uid for subsequent ConsFuns because the // DeadParamElim rewriter only rewrites the first arg list, // and sharing the same exprId would cause conflicting eliminable sets. - val firstResult = handleCallLike(c.uid, fun, args) + val firstResult = handleCallLike(c, args, opaqueTail = true) cc.constrain(firstResult, UnknownCons) rest.foreach: nextArgs => nextArgs.foreach(a => cc.constrain(processResult(a.value), UnknownCons)) UnknownProd case i@Instantiate(_, cls, argss) => + constrainConstructorEffect(i) constrainOpaqueResult(cls) argss.flatten.foreach(a => constrainOpaqueResult(a.value)) UnknownProd case lam@Lambda(ps, body) => - mkFunProdStrat("lam_res", ps :: Nil, body, lam.uid) + mkFunProdStrat("lam_res", ps :: Nil, body, lam.uid, Nil) case _: Tuple => lastWords("should be handled in CtorProducer") case Record(_, fields) => fields.foreach: @@ -1092,6 +1159,8 @@ class FlowConstraintSolver(val collector: FlowConstraintsCollector): val consumersWithSrcs = mutable.Buffer.empty[ConcreteCtorConsumer] val prodFunsWithDests = mutable.Buffer.empty[ProdFun] val consFunsWithSrcs = mutable.Buffer.empty[ConsFun] + val functionEffectVars = LinkedHashMap.empty[ConcreteId[FunId], StratVar] + val callEffectVars = LinkedHashMap.empty[ConcreteId[ResultId], StratVar] private def addCtorDest(c: Ctor, d: ConcreteCtorConsumer | MarkerConsStrat): Unit = if c.dests.isEmpty then ctorsWithDests += c @@ -1168,11 +1237,26 @@ class FlowConstraintSolver(val collector: FlowConstraintsCollector): def hasConcreteInstantiationId(prodOrCons: ProdStrat | ConsStrat): Boolean = prodOrCons match case s: StratWithOrigin[?] => s.instantiationId.isDefined case _ => true + def registerFunctionEffects(prod: ProdStrat): Unit = prod match + case p: ProdFun => + p.effect.foreach(effect => functionEffectVars(p.concreteId) = effect) + registerFunctionEffects(p.res) + case _ => () + // Trusted call metadata overrides all inferred contributions, not just unknown callees. + // Keep c.effect registered so a trusted-pure call still has a Pure summary. + def inferredCallEffect(c: ConsFun): Opt[StratVar] = + c.exprId.getResult match + case call: Call if !call.metadata.mayRaiseEffects => N + case _ => c.effect def handle(constraint: ProdStrat -> ConsStrat): Unit = assert: val (prod, cons) = constraint hasConcreteInstantiationId(prod) && hasConcreteInstantiationId(cons) + registerFunctionEffects(constraint._1) + constraint._2 match + case c: ConsFun => c.effect.foreach(effect => callEffectVars(c.concreteId) = effect) + case _ => () constraint match case (c: Ctor, d: Dtor) => addCtorDest(c, d) @@ -1213,6 +1297,11 @@ class FlowConstraintSolver(val collector: FlowConstraintsCollector): case v: StratVar => handle(arg, v.asIntoParam) case _ => () handle(p.res, c.res) + // The callee's latent effect becomes the effect observed at this call. + for + pEffect <- p.effect + cEffect <- inferredCallEffect(c) + do handle(pEffect, cEffect) case (p: ProdFun, UnknownCons) => addFunDest(p, UnknownCons) for a <- p.params do handle(UnknownProd, a) @@ -1234,6 +1323,8 @@ class FlowConstraintSolver(val collector: FlowConstraintsCollector): addFunSrc(c, UnknownProd) for a <- c.params do handle(a, UnknownCons) handle(UnknownProd, c.res) + // The conservative fallback. + inferredCallEffect(c).foreach(e => handle(UnsafeEta, e)) case (p: StratVar, c: StratVar) => if p.upperBounds.add(c) then for l <- p.lowerBounds do handle(l, c) diff --git a/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala b/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala index 947c56a25b..0ea4bd5869 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala @@ -37,6 +37,8 @@ enum Annot extends Located: case Async()(val toLoc: Opt[Loc]) case RaiseEffects()(val toLoc: Opt[Loc]) // Whether the function is guaranteed to not raise effects. + // * EffectAnalysis Annotations + // @pure: overriding annotation that the function is pure, i.e. it does not raise effects. case Pure()(val toLoc: Opt[Loc]) case Config(modify: hkmc2.Config => hkmc2.Config)(val toLoc: Opt[Loc]) // Marks if a function or lambda is one-shot, i.e. called at most once. diff --git a/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls b/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls index 23d42bfd4f..246cbf4650 100644 --- a/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls +++ b/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls @@ -128,7 +128,6 @@ fun foo(x) = { x.call(), print(42) } #config(effectHandlers: Some(EffectHandlers())) handle h = Object with {} print(h) -//│ //│ > Handler$h$ @@ -145,7 +144,6 @@ foo(h) print(42) #config(liftDefns: None) -//│ //│ > 42 @@ -165,12 +163,19 @@ deadParamConfig(42) #config(deforest: Some(Deforest(mono: false))) #config(effectHandlers: Some(EffectHandlers(stackSafety: None))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< data class Pair(a, b) fun fstConfig(p) = if p is Pair(x, y) then x fstConfig(Pair(1, 2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function fstConfig#0 @ fstConfig@fstConfig -> UnsafeEta +//│ deforest > function fstConfig#0 @ fstConfig@fstConfig -> UnsafeEta +//│ deforest > call fstConfig@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Pair⁰(1, 2) -> //│ deforest > match: p⁰ diff --git a/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls b/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls index 35b80f59b1..9d888791c0 100644 --- a/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls +++ b/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls @@ -7,6 +7,8 @@ data class (::) Cons(h, t) data object Nil data object A data object B +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> @@ -30,6 +32,14 @@ fun c(x) = B do set r = 2 r c(p(true)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> Pure +//│ deforest > function c#0 @ c@c -> Pure +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > call c@result @ -> Pure +//│ deforest > call p@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: x⁰ @@ -88,6 +98,26 @@ fun sumPlus(ls) = h :: t then h + sumPlus(t) r + 1 sumPlus(enum(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function sumPlus#0 @ sumPlus@sumPlus -> UnsafeEta +//│ deforest > function sumPlus#0 @ sumPlus@sumPlus -> UnsafeEta +//│ deforest > call +@result @ sumPlus@sumPlus -> Pure +//│ deforest > call +@result @ sumPlus@sumPlus -> Pure +//│ deforest > call +@result @ sumPlus@sumPlus -> Pure +//│ deforest > call +@result @ sumPlus@sumPlus -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call <@result @ enum@enum -> Pure +//│ deforest > call <@result @ enum@enum -> Pure +//│ deforest > call enum@result @ -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call sumPlus@result @ -> UnsafeEta +//│ deforest > call sumPlus@result @ sumPlus@sumPlus -> UnsafeEta +//│ deforest > call sumPlus@result @ sumPlus@sumPlus -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls⁰ @@ -170,6 +200,14 @@ fun c(x) = if x is A then 1 B then 2 c(p(true)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: x² diff --git a/hkmc2/shared/src/test/mlscript/deforest/append.mls b/hkmc2/shared/src/test/mlscript/deforest/append.mls index 207c27b4c0..a7dab33fa9 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/append.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/append.mls @@ -5,6 +5,8 @@ object Nil data class (::) Cons(h, t) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -23,6 +25,30 @@ appendThree of id(1 :: 2 :: Nil) id(3 :: 4 :: Nil) id(5 :: 6 :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append1#0 @ append1@append1 -> UnsafeEta +//│ deforest > function append1#0 @ appendThree@appendThree.append1@append1 -> UnsafeEta +//│ deforest > function append1#0 @ appendThree@appendThree.append1@append1 -> UnsafeEta +//│ deforest > function append2#0 @ append2@append2 -> UnsafeEta +//│ deforest > function append2#0 @ appendThree@appendThree.append2@append2 -> UnsafeEta +//│ deforest > function append2#0 @ appendThree@appendThree.append2@append2 -> UnsafeEta +//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta +//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append1@result @ append1@append1 -> UnsafeEta +//│ deforest > call append1@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append1@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append1@result @ appendThree@appendThree.append1@append1 -> UnsafeEta +//│ deforest > call append1@result @ appendThree@appendThree.append1@append1 -> UnsafeEta +//│ deforest > call append2@result @ append2@append2 -> UnsafeEta +//│ deforest > call append2@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append2@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append2@result @ appendThree@appendThree.append2@append2 -> UnsafeEta +//│ deforest > call append2@result @ appendThree@appendThree.append2@append2 -> UnsafeEta +//│ deforest > call appendThree@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Cons(1, Cons(2, Cons(3, Cons(4, Cons(5, Cons(6, Nil)))))) @@ -43,6 +69,56 @@ test of id(1 :: 2 :: Nil) id(3 :: 4 :: Nil) id(5 :: 6 :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append1#0 @ append1@append1 -> UnsafeEta +//│ deforest > function append1#0 @ append2@append2.append1@append1 -> UnsafeEta +//│ deforest > function append1#0 @ test@test.append1@append1 -> UnsafeEta +//│ deforest > function append1#0 @ test@test.append1@append1 -> UnsafeEta +//│ deforest > function append1#0 @ test@test.append2@append2.append1@append1 -> UnsafeEta +//│ deforest > function append1#0 @ test@test.append2@append2.append1@append1 -> UnsafeEta +//│ deforest > function append2#0 @ append2@append2 -> UnsafeEta +//│ deforest > function append2#0 @ test@test.append2@append2 -> UnsafeEta +//│ deforest > function append2#0 @ test@test.append2@append2 -> UnsafeEta +//│ deforest > function appendReified#0 @ append2@append2.appendReified@appendReified -> UnsafeEta +//│ deforest > function appendReified#0 @ appendReified@appendReified -> UnsafeEta +//│ deforest > function appendReified#0 @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta +//│ deforest > function appendReified#0 @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta +//│ deforest > function lambda#0 @ append2@append2 -> UnsafeEta +//│ deforest > function lambda#0 @ append2@append2 -> UnsafeEta +//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta +//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta +//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta +//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call append1@result @ append2@append2 -> UnsafeEta +//│ deforest > call append1@result @ test@test -> UnsafeEta +//│ deforest > call append1@result @ test@test -> UnsafeEta +//│ deforest > call append1@result @ test@test.append2@append2 -> UnsafeEta +//│ deforest > call append1@result @ test@test.append2@append2 -> UnsafeEta +//│ deforest > call append2@result @ append2@append2 -> UnsafeEta +//│ deforest > call append2@result @ test@test -> UnsafeEta +//│ deforest > call append2@result @ test@test -> UnsafeEta +//│ deforest > call append2@result @ test@test.append2@append2 -> UnsafeEta +//│ deforest > call append2@result @ test@test.append2@append2 -> UnsafeEta +//│ deforest > call appendReified@result @ append2@append2 -> UnsafeEta +//│ deforest > call appendReified@result @ append2@append2.appendReified@appendReified -> UnsafeEta +//│ deforest > call appendReified@result @ appendReified@appendReified -> UnsafeEta +//│ deforest > call appendReified@result @ test@test.append2@append2 -> UnsafeEta +//│ deforest > call appendReified@result @ test@test.append2@append2 -> UnsafeEta +//│ deforest > call appendReified@result @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta +//│ deforest > call appendReified@result @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call ys@result @ append1@append1 -> UnsafeEta +//│ deforest > call ys@result @ append2@append2.append1@append1 -> UnsafeEta +//│ deforest > call ys@result @ test@test.append1@append1 -> UnsafeEta +//│ deforest > call ys@result @ test@test.append1@append1 -> UnsafeEta +//│ deforest > call ys@result @ test@test.append2@append2.append1@append1 -> UnsafeEta +//│ deforest > call ys@result @ test@test.append2@append2.append1@append1 -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Cons(1, Cons(2, Cons(3, Cons(4, Cons(5, Cons(6, Nil)))))) @@ -61,6 +137,45 @@ appendThree of id(1 :: 2 :: Nil) id(3 :: 4 :: Nil) id(5 :: 6 :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta +//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta +//│ deforest > function idList#0 @ append@append.idList@idList -> UnsafeEta +//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > function idList#0 @ idList@idList -> UnsafeEta +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call appendThree@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call idList@result @ append@append -> UnsafeEta +//│ deforest > call idList@result @ append@append.idList@idList -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta +//│ deforest > call idList@result @ idList@idList -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h⁰, tmp⁰) -> //│ deforest > match: xs⁰ @@ -98,6 +213,25 @@ concat of id of (1 :: 2 :: Nil) :: (3 :: 4 :: Nil) :: (5 :: 6 :: Nil) :: Nil +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ concat@concat.append@append -> UnsafeEta +//│ deforest > function append#0 @ concat@concat.append@append -> UnsafeEta +//│ deforest > function concat#0 @ concat@concat -> UnsafeEta +//│ deforest > function concat#0 @ concat@concat -> UnsafeEta +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ concat@concat -> UnsafeEta +//│ deforest > call append@result @ concat@concat -> UnsafeEta +//│ deforest > call append@result @ concat@concat.append@append -> UnsafeEta +//│ deforest > call append@result @ concat@concat.append@append -> UnsafeEta +//│ deforest > call concat@result @ -> UnsafeEta +//│ deforest > call concat@result @ concat@concat -> UnsafeEta +//│ deforest > call concat@result @ concat@concat -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call idList@result @ append@append -> UnsafeEta +//│ deforest > call idList@result @ concat@concat.append@append -> UnsafeEta +//│ deforest > call idList@result @ concat@concat.append@append -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Cons(1, Cons(2, Cons(3, Cons(4, Cons(5, Cons(6, Nil)))))) diff --git a/hkmc2/shared/src/test/mlscript/deforest/basic.mls b/hkmc2/shared/src/test/mlscript/deforest/basic.mls index 4ab8c533bc..c4f1b63593 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/basic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/basic.mls @@ -11,12 +11,16 @@ data object C data object D data object Nil data class (::) Cons(h, t) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< :sir let lsit = [2, 1] in let useless = if lsit is [a, b] then 0 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [2, 1] -> //│ deforest > match: lsit⁰ @@ -50,6 +54,14 @@ fun p() = X(O) fun c(x) = if x is X(x) then x c(p()) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(O⁰) -> //│ deforest > match: x⁰ @@ -64,6 +76,14 @@ fun p() = X(Y(O)) fun f(x) = if x is X(Y(y)) then y f(p()) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp⁰) -> //│ deforest > match: x¹ @@ -142,6 +162,16 @@ fun f(x, res) = if x is if a is Y(y) then res + tmp f(p(), 2) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp¹) -> //│ deforest > match: x² @@ -163,6 +193,17 @@ fun f(x, y, res) = if x is let _d = () => y res + tmp + a f(X(1), Y(2), 3) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function _d#0 @ f@f -> Pure +//│ deforest > function _d#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(1) -> //│ deforest > match: x³ @@ -175,6 +216,18 @@ f(X(1), Y(2), 3) fun c(x, d) = if x is X(a) then c(X(a), d) () => c(X(3), 2) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ lambda@lambda.c@c -> UnsafeEta +//│ deforest > function c#0 @ lambda@lambda.c@c -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta +//│ deforest > call c@result @ c@c -> UnsafeEta +//│ deforest > call c@result @ lambda@lambda -> UnsafeEta +//│ deforest > call c@result @ lambda@lambda -> UnsafeEta +//│ deforest > call c@result @ lambda@lambda.c@c -> UnsafeEta +//│ deforest > call c@result @ lambda@lambda.c@c -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(a²) -> //│ deforest > match: x⁴ @@ -199,6 +252,26 @@ fun c() = b() fun p(x) = if x is O then 2 p(c()) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function a#0 @ a@a -> Pure +//│ deforest > function a#0 @ b@b.a@a -> Pure +//│ deforest > function a#0 @ c@c.b@b.a@a -> Pure +//│ deforest > function a#0 @ c@c.b@b.a@a -> Pure +//│ deforest > function b#0 @ b@b -> Pure +//│ deforest > function b#0 @ c@c.b@b -> Pure +//│ deforest > function b#0 @ c@c.b@b -> Pure +//│ deforest > function c#0 @ c@c -> Pure +//│ deforest > function c#0 @ c@c -> Pure +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call a@result @ b@b -> Pure +//│ deforest > call a@result @ c@c.b@b -> Pure +//│ deforest > call a@result @ c@c.b@b -> Pure +//│ deforest > call b@result @ c@c -> Pure +//│ deforest > call b@result @ c@c -> Pure +//│ deforest > call c@result @ -> Pure +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > O⁰ -> //│ deforest > match: x⁵ @@ -210,6 +283,9 @@ p(c()) :expect 3 if [1, 2] is [a, b] then a + b +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call +@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [1, 2] -> //│ deforest > match: scrut⁰ @@ -242,6 +318,13 @@ if [1, 2] is fun f(x) = if x is [a,b] then a + b f([1,2]) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [1, 2] -> //│ deforest > match: x⁶ @@ -255,6 +338,12 @@ f([1,2]) fun f(x) = if x is O then 2 f(id(O)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 2 @@ -266,6 +355,11 @@ fun f() = if x is O then 0 f() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 0 @@ -276,6 +370,11 @@ f() fun f(x) = if x is A(x) then x f(A(1)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(1) -> //│ deforest > match: x⁷ @@ -288,6 +387,13 @@ f(A(1)) fun f(x) = if x is A(a) then x.A#x + a f(A(1)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(1) -> //│ deforest > match: x⁹ @@ -301,6 +407,14 @@ f(A(1)) fun f(x) = if x is A(x) then 2 f(A(2)) + f(A(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(3) -> //│ deforest > match: x¹⁰ @@ -318,6 +432,13 @@ fun localFuse(x) = if A(x) is if localFuse(3) is B(a) then a localFuse(4) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function localFuse#0 @ localFuse@localFuse -> UnsafeEta +//│ deforest > function localFuse#0 @ localFuse@localFuse -> UnsafeEta +//│ deforest > function localFuse#0 @ localFuse@localFuse -> UnsafeEta +//│ deforest > call localFuse@result @ -> UnsafeEta +//│ deforest > call localFuse@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(x¹¹) -> //│ deforest > match: scrut¹ @@ -343,6 +464,16 @@ fun g(x) = if x is fun f(x) = x.A#x let o = A(1) g(o) + f(o) + o.A#x +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call f@result @ -> Pure +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 3 @@ -354,6 +485,10 @@ let x = if A(0) is A then 1 let f() = x f() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(0) -> //│ deforest > match: scrut³ @@ -364,6 +499,9 @@ f() :fixme f() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ ═══[RUNTIME ERROR] TypeError: f10 is not a function @@ -375,6 +513,16 @@ fun inner(y, z) = if y is fun dtor(x) = if x is A then inner(B(4), x.A#x) dtor(A(B(0))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function dtor#0 @ dtor@dtor -> UnsafeEta +//│ deforest > function dtor#0 @ dtor@dtor -> UnsafeEta +//│ deforest > function inner#0 @ dtor@dtor.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ dtor@dtor.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ inner@inner -> UnsafeEta +//│ deforest > call dtor@result @ -> UnsafeEta +//│ deforest > call inner@result @ dtor@dtor -> UnsafeEta +//│ deforest > call inner@result @ dtor@dtor -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰(4) -> //│ deforest > match: y¹ diff --git a/hkmc2/shared/src/test/mlscript/deforest/clashes.mls b/hkmc2/shared/src/test/mlscript/deforest/clashes.mls index cee48bd145..508bec38b5 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/clashes.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/clashes.mls @@ -3,11 +3,15 @@ data class A(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< data class (::) Cons(h, t) object Nil +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -26,6 +30,56 @@ fun badWrap(n) = f1(x) + f2(x) x f1(badWrap(4)) + f2(badWrap(5)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function badWrap#0 @ badWrap@badWrap -> UnsafeEta +//│ deforest > function badWrap#0 @ badWrap@badWrap -> UnsafeEta +//│ deforest > function badWrap#0 @ badWrap@badWrap -> UnsafeEta +//│ deforest > function f1#0 @ badWrap@badWrap.f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ badWrap@badWrap.f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ badWrap@badWrap.f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ badWrap@badWrap.f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ badWrap@badWrap.f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ badWrap@badWrap.f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function to#0 @ badWrap@badWrap.to@to -> UnsafeEta +//│ deforest > function to#0 @ badWrap@badWrap.to@to -> UnsafeEta +//│ deforest > function to#0 @ badWrap@badWrap.to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ badWrap@badWrap.f2@f2 -> Pure +//│ deforest > call +@result @ badWrap@badWrap.f2@f2 -> Pure +//│ deforest > call +@result @ badWrap@badWrap.f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call -@result @ badWrap@badWrap.to@to -> Pure +//│ deforest > call -@result @ badWrap@badWrap.to@to -> Pure +//│ deforest > call -@result @ badWrap@badWrap.to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call >@result @ badWrap@badWrap.to@to -> Pure +//│ deforest > call >@result @ badWrap@badWrap.to@to -> Pure +//│ deforest > call >@result @ badWrap@badWrap.to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call badWrap@result @ -> UnsafeEta +//│ deforest > call badWrap@result @ -> UnsafeEta +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f1@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call f1@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call f1@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call f2@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call f2@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call f2@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call to@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call to@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call to@result @ badWrap@badWrap -> UnsafeEta +//│ deforest > call to@result @ badWrap@badWrap.to@to -> UnsafeEta +//│ deforest > call to@result @ badWrap@badWrap.to@to -> UnsafeEta +//│ deforest > call to@result @ badWrap@badWrap.to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 10 @@ -40,6 +94,28 @@ let two = p(2) fun f1(p) = if p is A(a) then a + 1 fun f2(p) = if p is A(b) then b + 2 f1(one) + f2(one) + f2(two) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(x⁰) -> //│ deforest > match: p⁰ @@ -60,6 +136,27 @@ let res2 = p(x) // x flows into this call-site result let res3 = p(y) // y flows into this call-site result // f1(res1) + f2(res1) + f1(res2) + f2(res3) f1(res1) + f1(res2) + f2(res3) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call p@result @ -> Pure +//│ deforest > call p@result @ -> Pure +//│ deforest > call p@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 5 @@ -79,6 +176,22 @@ fun p(x, clashedCtor) = else clashedCtor let clashed = A(3) f1(p(1, clashed)) + f2(p(2, clashed)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 4 diff --git a/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls b/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls index 70d783d6c9..482b04113b 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls @@ -41,6 +41,16 @@ fun f(a) = if a is C then C else D (x => 0)(f(f(C))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > call f@result @ -> Pure +//│ deforest > call f@result @ -> Pure +//│ deforest > call lambda@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > C⁰ -> //│ deforest > match: a⁰ @@ -61,6 +71,16 @@ fun maxOpt(ls) = if ls is None then Some(h) Some(m) then if m > h then Some(m) else Some(h) maxOpt(id(1 :: 2 :: Nil)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function maxOpt#0 @ maxOpt@maxOpt -> UnsafeEta +//│ deforest > function maxOpt#0 @ maxOpt@maxOpt -> UnsafeEta +//│ deforest > call >@result @ maxOpt@maxOpt -> Pure +//│ deforest > call >@result @ maxOpt@maxOpt -> Pure +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call maxOpt@result @ -> UnsafeEta +//│ deforest > call maxOpt@result @ maxOpt@maxOpt -> UnsafeEta +//│ deforest > call maxOpt@result @ maxOpt@maxOpt -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Some(2) @@ -75,6 +95,17 @@ fun modSome(x, m) = if x is else Some(n) None then None modSome(Some(17), 3) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function modSome#0 @ modSome@modSome -> UnsafeEta +//│ deforest > function modSome#0 @ modSome@modSome -> UnsafeEta +//│ deforest > call -@result @ modSome@modSome -> Pure +//│ deforest > call -@result @ modSome@modSome -> Pure +//│ deforest > call >=@result @ modSome@modSome -> Pure +//│ deforest > call >=@result @ modSome@modSome -> Pure +//│ deforest > call modSome@result @ -> UnsafeEta +//│ deforest > call modSome@result @ modSome@modSome -> UnsafeEta +//│ deforest > call modSome@result @ modSome@modSome -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Some⁰(tmp⁰) -> //│ deforest > match: x⁰ @@ -138,6 +169,20 @@ fun maxOpt2(ls, x) = if ls is h > m then maxOpt2(t, Some(h)) else maxOpt2(t, Some(m)) maxOpt2(id(1 :: 2 :: 3 :: Nil), None) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function maxOpt2#0 @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > function maxOpt2#0 @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > call >@result @ maxOpt2@maxOpt2 -> Pure +//│ deforest > call >@result @ maxOpt2@maxOpt2 -> Pure +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call maxOpt2@result @ -> UnsafeEta +//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Some(3) @@ -148,6 +193,19 @@ fun zipWith(xsys, f) = if xsys is [hx :: tx, hy :: ty] then f(hx, hy) :: zipWith([tx, ty], f) [Nil, Nil] then Nil zipWith([id(Nil), id(Nil)], (x, y) => x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function zipWith#0 @ zipWith@zipWith -> UnsafeEta +//│ deforest > function zipWith#0 @ zipWith@zipWith -> UnsafeEta +//│ deforest > call f@result @ zipWith@zipWith -> Pure +//│ deforest > call f@result @ zipWith@zipWith -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call zipWith@result @ -> UnsafeEta +//│ deforest > call zipWith@result @ zipWith@zipWith -> UnsafeEta +//│ deforest > call zipWith@result @ zipWith@zipWith -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [tx⁰, ty⁰] -> //│ deforest > match: xsys⁰ diff --git a/hkmc2/shared/src/test/mlscript/deforest/determinism.mls b/hkmc2/shared/src/test/mlscript/deforest/determinism.mls index 5eda4eebe8..13c08a2cb1 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/determinism.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/determinism.mls @@ -8,6 +8,8 @@ data class B(a, b, c, d, e) :expect 0 if B(1,2,3,4,5) is B(a,b,c,d,e) then 0 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰(1, 2, 3, 4, 5) -> //│ deforest > match: scrut⁰ @@ -54,6 +56,11 @@ if B(1,2,3,4,5) is fun c2(x) = if x is A(A(A(A(A(A(a)))))) then a c2 of A(A(A(A(A(A(1)))))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(tmp⁰) -> //│ deforest > match: x⁰ diff --git a/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls b/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls index 37041a8b7f..30619cf2ce 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls @@ -22,6 +22,22 @@ fun fix(x) = else fix(res) fix +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function dl#0 @ dl@dl -> UnsafeEta +//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > call dl@result @ dl@dl -> UnsafeEta +//│ deforest > call dl@result @ fix@fix -> UnsafeEta +//│ deforest > call dl@result @ fix@fix -> UnsafeEta +//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > call lseq@result @ fix@fix -> UnsafeEta +//│ deforest > call lseq@result @ fix@fix -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = fun fix @@ -40,6 +56,24 @@ fun fix(x, fuel) = else fix(res, fuel - 1) fix +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function dl#0 @ dl@dl -> UnsafeEta +//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > call -@result @ fix@fix -> Pure +//│ deforest > call -@result @ fix@fix -> Pure +//│ deforest > call dl@result @ dl@dl -> UnsafeEta +//│ deforest > call dl@result @ fix@fix -> UnsafeEta +//│ deforest > call dl@result @ fix@fix -> UnsafeEta +//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > call equals@result @ fix@fix -> UnsafeEta +//│ deforest > call equals@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = fun fix @@ -59,6 +93,32 @@ fun fix(x, fuel) = else fix(res, fuel - 1) fix +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function dl#0 @ dl@dl -> UnsafeEta +//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > function dlHelper#0 @ dl@dl.dlHelper@dlHelper -> UnsafeEta +//│ deforest > function dlHelper#0 @ dlHelper@dlHelper -> UnsafeEta +//│ deforest > function dlHelper#0 @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta +//│ deforest > function dlHelper#0 @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > call -@result @ fix@fix -> Pure +//│ deforest > call -@result @ fix@fix -> Pure +//│ deforest > call dl@result @ fix@fix -> UnsafeEta +//│ deforest > call dl@result @ fix@fix -> UnsafeEta +//│ deforest > call dlHelper@result @ dl@dl -> UnsafeEta +//│ deforest > call dlHelper@result @ dl@dl.dlHelper@dlHelper -> UnsafeEta +//│ deforest > call dlHelper@result @ dlHelper@dlHelper -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dl@dl -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta +//│ deforest > call equals@result @ fix@fix -> UnsafeEta +//│ deforest > call equals@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = fun fix @@ -77,6 +137,26 @@ fun fix(x, fuel) = else fix(res, fuel - 1) id(fix(Nil, 1000)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function dlHelper#0 @ dlHelper@dlHelper -> UnsafeEta +//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > call -@result @ fix@fix -> Pure +//│ deforest > call -@result @ fix@fix -> Pure +//│ deforest > call dlHelper@result @ dlHelper@dlHelper -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > call equals@result @ fix@fix -> UnsafeEta +//│ deforest > call equals@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Nil @@ -95,6 +175,21 @@ fun fix(x) = Nil then Nil x :: xs then fix(dlHelper(x, xs)) fix(2 :: 3 :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function dlHelper#0 @ dlHelper@dlHelper -> UnsafeEta +//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > function fix#0 @ fix@fix -> UnsafeEta +//│ deforest > call dlHelper@result @ dlHelper@dlHelper -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta +//│ deforest > call fix@result @ -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Nil @@ -111,6 +206,23 @@ fun f(x) = if x is Nil then Nil fun loop(l, n) = if n > 0 then loop(f(l), n - 1) else l id(loop(Nil, 2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ loop@loop.f@f -> UnsafeEta +//│ deforest > function f#0 @ loop@loop.f@f -> UnsafeEta +//│ deforest > function loop#0 @ loop@loop -> UnsafeEta +//│ deforest > function loop#0 @ loop@loop -> UnsafeEta +//│ deforest > call -@result @ loop@loop -> Pure +//│ deforest > call -@result @ loop@loop -> Pure +//│ deforest > call >@result @ loop@loop -> Pure +//│ deforest > call >@result @ loop@loop -> Pure +//│ deforest > call f@result @ loop@loop -> UnsafeEta +//│ deforest > call f@result @ loop@loop -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call loop@result @ -> UnsafeEta +//│ deforest > call loop@result @ loop@loop -> UnsafeEta +//│ deforest > call loop@result @ loop@loop -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Nil diff --git a/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls b/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls index 24eda9a541..5bcf9b02fa 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls @@ -12,6 +12,8 @@ data class Box(v: Int) data class Pair(a: Int, b: Str) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ ———————————————| Lowered IR |——————————————————————————————————————————————————————————————————————— @@ -45,6 +47,9 @@ fun selected(n: Int, k: Str) = let b = Box(n) if b is Box(x) then [x, k] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function selected#0 @ selected@selected -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Box¹(n⁰) -> //│ deforest > match: b² @@ -79,6 +84,9 @@ fun withRest(n: Int, k: Str) = Box(x) then x else 0 [r, k] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function withRest#0 @ withRest@withRest -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Box¹(n¹) -> //│ deforest > match: b³ @@ -113,6 +121,9 @@ fun noFields(n: Int, s: Str) = let p = Pair(n, s) if p is Pair then 1 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function noFields#0 @ noFields@noFields -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Pair¹(n², s⁰) -> //│ deforest > match: p⁰ diff --git a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls index ed996642f1..a3604d2557 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls @@ -10,6 +10,8 @@ data object A data object B data object O data object Nil +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> @@ -21,6 +23,14 @@ fun p(x) = X(x) fun c(x) = if x is X(a) then a c(p(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(x⁰) -> //│ deforest > match: x¹ @@ -40,6 +50,14 @@ fun c(x) = if x is A then 1 B then 2 c(p(true)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > function p#0 @ p@p -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: x² @@ -59,6 +77,17 @@ fun f(x) = if x is fun g(y) = if y is Y(o) then o g(f(p())) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp⁰) -> //│ deforest > match: x³ @@ -82,6 +111,14 @@ fun p(b) = fun c(x) = if x is X(Y(y)) then y c(p(true)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp¹) -> //│ deforest > match: x⁴ @@ -109,6 +146,21 @@ fun main(x) = X(Y(y)) then y c(p(2)) main(3) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ main@main -> UnsafeEta +//│ deforest > function c#0 @ main@main -> UnsafeEta +//│ deforest > function main#0 @ main@main -> UnsafeEta +//│ deforest > function main#0 @ main@main -> UnsafeEta +//│ deforest > function p#0 @ main@main -> UnsafeEta +//│ deforest > function p#0 @ main@main -> UnsafeEta +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call c@result @ main@main -> UnsafeEta +//│ deforest > call c@result @ main@main -> UnsafeEta +//│ deforest > call main@result @ -> UnsafeEta +//│ deforest > call p@result @ main@main -> UnsafeEta +//│ deforest > call p@result @ main@main -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp³) -> //│ deforest > match: x⁵ @@ -136,6 +188,14 @@ fun p(x) = X(x) fun c(x) = if x is X(a) then a c(p(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(x⁶) -> //│ deforest > match: x⁷ diff --git a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls index 5d0af3a286..780cb6bedb 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls @@ -6,6 +6,8 @@ data class (::) Cons(h, t) data object Nil +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> @@ -19,6 +21,24 @@ fun sum(ls, acc) = if ls is Nil then acc h :: t then sum(t, h + acc) sum(enum(5), 0) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call <@result @ enum@enum -> Pure +//│ deforest > call <@result @ enum@enum -> Pure +//│ deforest > call enum@result @ -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls⁰ @@ -102,6 +122,29 @@ fun len(ls) = if ls is Nil then 0 h :: t then 1 + len(t) len(flatten(id((1 :: 2 :: Nil) :: (3 :: Nil) :: Nil))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta +//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta +//│ deforest > function len#0 @ len@len -> UnsafeEta +//│ deforest > function len#0 @ len@len -> UnsafeEta +//│ deforest > call +@result @ len@len -> Pure +//│ deforest > call +@result @ len@len -> Pure +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > call flatten@result @ -> UnsafeEta +//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta +//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call len@result @ -> UnsafeEta +//│ deforest > call len@result @ len@len -> UnsafeEta +//│ deforest > call len@result @ len@len -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls¹ @@ -204,6 +247,9 @@ len(flatten(id((1 :: 2 :: Nil) :: (3 :: Nil) :: Nil))) // the analysis shouldn't stackoverflow :flowBasedOpt debugEta fun f(x) = f +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> diff --git a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls index e69111885d..dd04d88b98 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls @@ -5,6 +5,8 @@ data class (::) Cons(h, t) data object Nil //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -12,6 +14,8 @@ data class AA(x) data class BB(x) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -19,6 +23,8 @@ data class Many(x) data class Once(x) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -30,6 +36,11 @@ fun c(p) = if p is AA(v) then v c(AA(3)) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(3) -> //│ deforest > match: p⁰ @@ -43,6 +54,13 @@ fun c(x) = if x is AA(_) then x.AA#x + x.AA#x c(AA(7)) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(7) -> //│ deforest > match: x¹ @@ -68,6 +86,19 @@ c(AA(7)) //│ deforest > p_for_c⁰ //│ deforest > tmp⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function lambda#0 @ c@c -> UnsafeEta +//│ deforest > function lambda#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call cl@result @ c@c -> UnsafeEta +//│ deforest > call cl@result @ c@c -> UnsafeEta +//│ deforest > call cl@result @ c@c -> UnsafeEta +//│ deforest > call cl@result @ c@c -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 14 @@ -81,6 +112,19 @@ fun affine_branched(x, y, cons_y) = if x is affine_branched(AA(0), AA(1), (y) => if y is AA(x) then x + 2) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function affine_branched#0 @ affine_branched@affine_branched -> UnsafeEta +//│ deforest > function affine_branched#0 @ affine_branched@affine_branched -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call affine_branched@result @ -> UnsafeEta +//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta +//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta +//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta +//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(1) -> //│ deforest > match: y⁰ @@ -99,6 +143,14 @@ let p = AA(10) in //│ deforest > >>> non-affine syms >>> //│ deforest > p¹ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 0 @@ -116,6 +168,19 @@ apply(c, AA(3)) //│ deforest > x_for_apply¹ //│ deforest > x_for_apply⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function apply#0 @ apply@apply -> UnsafeEta +//│ deforest > function apply#0 @ apply@apply -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ apply@apply -> Pure +//│ deforest > call +@result @ apply@apply -> Pure +//│ deforest > call apply@result @ -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 6 @@ -129,6 +194,15 @@ c(AA(0), AA(3)) //│ deforest > x_for_c¹ //│ deforest > x_for_c⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(0) -> //│ deforest > match: k⁰ @@ -150,6 +224,13 @@ c(AA(1)) //│ deforest > y_for_c¹ //│ deforest > y_for_c⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function _d#0 @ c@c -> Pure +//│ deforest > function _d#0 @ c@c -> Pure +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 0 @@ -165,6 +246,15 @@ let p = AA(AA(AA(10))) in //│ deforest > tmp¹ //│ deforest > tmp⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c1#0 @ c1@c1 -> Pure +//│ deforest > function c1#0 @ c1@c1 -> Pure +//│ deforest > function c2#0 @ c2@c2 -> Pure +//│ deforest > function c2#0 @ c2@c2 -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call c1@result @ -> Pure +//│ deforest > call c2@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 11 @@ -183,6 +273,21 @@ apply(c1, c2, Many(Once(10))) //│ deforest > tmp¹ //│ deforest > tmp⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function apply#0 @ apply@apply -> UnsafeEta +//│ deforest > function apply#0 @ apply@apply -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > call +@result @ apply@apply -> Pure +//│ deforest > call +@result @ apply@apply -> Pure +//│ deforest > call apply@result @ -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > call g@result @ apply@apply -> UnsafeEta +//│ deforest > call g@result @ apply@apply -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 13 @@ -208,6 +313,24 @@ nest_consume(nest_pickB, nest_prod(10)) //│ deforest > tmp_for_nest_prod⁰ //│ deforest > x_for_nest_prod⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function nest_consume#0 @ nest_consume@nest_consume -> UnsafeEta +//│ deforest > function nest_consume#0 @ nest_consume@nest_consume -> UnsafeEta +//│ deforest > function nest_pickB#0 @ nest_pickB@nest_pickB -> UnsafeEta +//│ deforest > function nest_pickB#0 @ nest_pickB@nest_pickB -> UnsafeEta +//│ deforest > function nest_prod#0 @ nest_prod@nest_prod -> UnsafeEta +//│ deforest > function nest_prod#0 @ nest_prod@nest_prod -> UnsafeEta +//│ deforest > call +@result @ nest_consume@nest_consume -> Pure +//│ deforest > call +@result @ nest_consume@nest_consume -> Pure +//│ deforest > call +@result @ nest_pickB@nest_pickB -> Pure +//│ deforest > call +@result @ nest_pickB@nest_pickB -> Pure +//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta +//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta +//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta +//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta +//│ deforest > call nest_consume@result @ -> UnsafeEta +//│ deforest > call nest_prod@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> //│ deforest > match: p¹ @@ -235,6 +358,24 @@ length(from(5, Nil)) //│ deforest > acc_for_from¹ //│ deforest > acc_for_from⁰ //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function from#0 @ from@from -> UnsafeEta +//│ deforest > function from#0 @ from@from -> UnsafeEta +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call -@result @ from@from -> Pure +//│ deforest > call -@result @ from@from -> Pure +//│ deforest > call equals@result @ from@from -> UnsafeEta +//│ deforest > call equals@result @ from@from -> UnsafeEta +//│ deforest > call from@result @ -> UnsafeEta +//│ deforest > call from@result @ from@from -> UnsafeEta +//│ deforest > call from@result @ from@from -> UnsafeEta +//│ deforest > call length@result @ -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 5 @@ -252,6 +393,21 @@ length(append(id(1 :: Nil), 2 :: Nil)) //│ deforest > <<< non-affine syms <<< //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call append@result @ -> UnsafeEta +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call length@result @ -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h⁰, tmp¹) -> //│ deforest > match: ls⁰ @@ -283,6 +439,29 @@ length(ping(id(1 :: 2 :: Nil), 3 :: 4 :: Nil)) //│ deforest > <<< non-affine syms <<< //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > function ping#0 @ ping@ping -> UnsafeEta +//│ deforest > function ping#0 @ ping@ping -> UnsafeEta +//│ deforest > function ping#0 @ pong@pong -> UnsafeEta +//│ deforest > function pong#0 @ ping@ping -> UnsafeEta +//│ deforest > function pong#0 @ ping@ping -> UnsafeEta +//│ deforest > function pong#0 @ pong@pong -> UnsafeEta +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call length@result @ -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > call ping@result @ -> UnsafeEta +//│ deforest > call ping@result @ ping@ping -> UnsafeEta +//│ deforest > call ping@result @ ping@ping -> UnsafeEta +//│ deforest > call ping@result @ pong@pong -> UnsafeEta +//│ deforest > call pong@result @ ping@ping -> UnsafeEta +//│ deforest > call pong@result @ ping@ping -> UnsafeEta +//│ deforest > call pong@result @ pong@pong -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(3, tmp²) -> //│ deforest > match: ls¹ @@ -313,6 +492,21 @@ sum(append(id(Nil), Nil), 0) //│ deforest > <<< non-affine syms <<< //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call append@result @ -> UnsafeEta +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h², tmp³) -> //│ deforest > match: ls² @@ -354,6 +548,29 @@ length(flatten(id((1 :: Nil) :: Nil))) //│ deforest > <<< non-affine syms <<< //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta +//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > function length#0 @ length@length -> UnsafeEta +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call +@result @ length@length -> Pure +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > call flatten@result @ -> UnsafeEta +//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta +//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call length@result @ -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h³, tmp⁴) -> //│ deforest > match: ls³ @@ -378,6 +595,15 @@ alias_then_patmat(Cons(12, 13)) //│ deforest > <<< non-affine syms <<< //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function alias_then_patmat#0 @ alias_then_patmat@alias_then_patmat -> UnsafeEta +//│ deforest > function alias_then_patmat#0 @ alias_then_patmat@alias_then_patmat -> UnsafeEta +//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure +//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure +//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure +//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure +//│ deforest > call alias_then_patmat@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 37 @@ -394,6 +620,19 @@ foo of AA of () => 1 //│ deforest > <<< non-affine syms <<< //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > call +@result @ foo@foo -> Pure +//│ deforest > call +@result @ foo@foo -> Pure +//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > call x@result @ foo@foo -> Pure +//│ deforest > call x@result @ foo@foo -> Pure +//│ deforest > call x@result @ foo@foo -> UnsafeEta +//│ deforest > call x@result @ foo@foo -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(lambda⁰) -> //│ deforest > match: a⁰ @@ -419,6 +658,19 @@ foo of AA of () => 1 //│ deforest > <<< non-affine syms <<< //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > call +@result @ foo@foo -> Pure +//│ deforest > call +@result @ foo@foo -> Pure +//│ deforest > call f@result @ foo@foo -> Pure +//│ deforest > call f@result @ foo@foo -> Pure +//│ deforest > call f@result @ foo@foo -> UnsafeEta +//│ deforest > call f@result @ foo@foo -> UnsafeEta +//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(lambda¹) -> //│ deforest > match: a¹ diff --git a/hkmc2/shared/src/test/mlscript/deforest/imperative.mls b/hkmc2/shared/src/test/mlscript/deforest/imperative.mls index b5d22bdb24..ff0af9146d 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/imperative.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/imperative.mls @@ -9,6 +9,8 @@ object B // class BB(bb) // object None // class Some(value) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -19,6 +21,10 @@ fun foo(x) = if x is A then 1 B then 2 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > call print@result @ foo@foo -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ x = A @@ -28,6 +34,11 @@ let x = if true then A else B fun foo(x) = if x is A do print(123) if x is B do print(456) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > call print@result @ foo@foo -> UnsafeEta +//│ deforest > call print@result @ foo@foo -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ x = A @@ -43,6 +54,21 @@ fun bar(v) = if v is A then 1 B then 2 foo(bar, 123) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function bar#0 @ bar@bar -> UnsafeEta +//│ deforest > function bar#0 @ bar@bar -> UnsafeEta +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > call ===@result @ foo@foo -> Pure +//│ deforest > call ===@result @ foo@foo -> Pure +//│ deforest > call >@result @ foo@foo -> Pure +//│ deforest > call >@result @ foo@foo -> Pure +//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > call k@result @ foo@foo -> UnsafeEta +//│ deforest > call k@result @ foo@foo -> UnsafeEta +//│ deforest > call k@result @ foo@foo -> UnsafeEta +//│ deforest > call k@result @ foo@foo -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: v⁰ diff --git a/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls b/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls index 254b119b14..55cf18ae39 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls @@ -6,6 +6,8 @@ data class (::) Cons(h, t) data class Pair(a, b) object A object B +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -26,6 +28,81 @@ fun lscomp1(ls) = if ls is lscomp2(zip(enumFromTo(x, x + 2), enumFromTo(y1, y1 + 1))) else Nil lscomp1(zip(enumFromTo(1, 3), enumFromTo(2, 4))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function zip#0 @ lscomp1@lscomp1.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ lscomp1@lscomp1.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ zip@zip -> UnsafeEta +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure +//│ deforest > call enumFromTo@result @ -> UnsafeEta +//│ deforest > call enumFromTo@result @ -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call equals@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call equals@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp1@result @ -> UnsafeEta +//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call zip@result @ -> UnsafeEta +//│ deforest > call zip@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call zip@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call zip@result @ lscomp1@lscomp1.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ lscomp1@lscomp1.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: xs_zip⁰ @@ -104,6 +181,41 @@ fun f1(a1) = if a1 is concatMap(f2, Pair(1, 3) :: Pair(2, 3) :: Pair(a, b) :: Nil) else Nil concatMap(f1, Pair(5, 10) :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > function append#0 @ concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > function append#0 @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > function append#0 @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > function concatMap#0 @ concatMap@concatMap -> UnsafeEta +//│ deforest > function concatMap#0 @ concatMap@concatMap -> UnsafeEta +//│ deforest > function concatMap#0 @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > function concatMap#0 @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f1@f1 -> UnsafeEta +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ concatMap@concatMap -> UnsafeEta +//│ deforest > call append@result @ concatMap@concatMap -> UnsafeEta +//│ deforest > call append@result @ concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > call append@result @ concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > call append@result @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > call append@result @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > call append@result @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > call append@result @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta +//│ deforest > call concatMap@result @ -> UnsafeEta +//│ deforest > call concatMap@result @ concatMap@concatMap -> UnsafeEta +//│ deforest > call concatMap@result @ concatMap@concatMap -> UnsafeEta +//│ deforest > call concatMap@result @ f1@f1 -> UnsafeEta +//│ deforest > call concatMap@result @ f1@f1 -> UnsafeEta +//│ deforest > call concatMap@result @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > call concatMap@result @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > call f@result @ concatMap@concatMap -> UnsafeEta +//│ deforest > call f@result @ concatMap@concatMap -> UnsafeEta +//│ deforest > call f@result @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > call f@result @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(tmp³, Nil⁰) -> //│ deforest > match: xs⁰ @@ -204,6 +316,24 @@ fun lscomp2(ls2, h1, t1) = if ls2 is h2 :: t2 then Pair(h1, h2) :: lscomp2(t2, h1, t1) Nil then lscomp1(t1, ls2) lscomp1(1 :: 2 :: Nil, 3 :: 4 :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function lscomp1#0 @ lscomp2@lscomp2 -> UnsafeEta +//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > function lscomp2#0 @ lscomp2@lscomp2 -> UnsafeEta +//│ deforest > call lscomp1@result @ -> UnsafeEta +//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp1@result @ lscomp2@lscomp2 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp2@lscomp2 -> UnsafeEta +//│ deforest > call lscomp2@result @ lscomp2@lscomp2 -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp¹¹) -> //│ deforest > match: ls1⁰ @@ -226,6 +356,15 @@ fun lscomp(ls) = if ls is if A is A then lscomp(1 :: 2 :: 3 :: Nil) B then Nil +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lscomp#0 @ lscomp@lscomp -> UnsafeEta +//│ deforest > function lscomp#0 @ lscomp@lscomp -> UnsafeEta +//│ deforest > call +@result @ lscomp@lscomp -> Pure +//│ deforest > call +@result @ lscomp@lscomp -> Pure +//│ deforest > call lscomp@result @ -> UnsafeEta +//│ deforest > call lscomp@result @ lscomp@lscomp -> UnsafeEta +//│ deforest > call lscomp@result @ lscomp@lscomp -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp¹²) -> //│ deforest > match: ls¹ @@ -258,6 +397,23 @@ fun h() = lscomp2(1 :: 2 :: 3 :: Nil) lscomp1(1 :: 2 :: 3 :: Nil) h() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function h#0 @ h@h -> UnsafeEta +//│ deforest > function h#0 @ h@h -> UnsafeEta +//│ deforest > function lscomp1#0 @ h@h -> UnsafeEta +//│ deforest > function lscomp1#0 @ h@h -> UnsafeEta +//│ deforest > function lscomp2#0 @ h@h -> UnsafeEta +//│ deforest > function lscomp2#0 @ h@h -> UnsafeEta +//│ deforest > call h@result @ -> UnsafeEta +//│ deforest > call lscomp1@result @ h@h -> UnsafeEta +//│ deforest > call lscomp1@result @ h@h -> UnsafeEta +//│ deforest > call lscomp1@result @ h@h -> UnsafeEta +//│ deforest > call lscomp1@result @ h@h -> UnsafeEta +//│ deforest > call lscomp2@result @ h@h -> UnsafeEta +//│ deforest > call lscomp2@result @ h@h -> UnsafeEta +//│ deforest > call lscomp2@result @ h@h -> UnsafeEta +//│ deforest > call lscomp2@result @ h@h -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp¹⁴) -> //│ deforest > match: ls² diff --git a/hkmc2/shared/src/test/mlscript/deforest/module.mls b/hkmc2/shared/src/test/mlscript/deforest/module.mls index 319c8b6fd8..90906a3667 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/module.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/module.mls @@ -13,6 +13,19 @@ module M with fun f(x) = if x is XX(YY(y)) then h() M.f(M.p()) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function h#0 @ f@f.h@h -> Pure +//│ deforest > function h#0 @ f@f.h@h -> Pure +//│ deforest > function h#0 @ h@h -> Pure +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > M⁰.this.XX⁰(tmp⁰) -> //│ deforest > match: x⁰ @@ -40,6 +53,46 @@ module DeforestList with fun main() = DeforestList.sum(DeforestList.enum(3)) val res = DeforestList.sum(DeforestList.enum(100)) DeforestList.res + DeforestList.main() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta +//│ deforest > function main#0 @ main@main -> UnsafeEta +//│ deforest > function main#0 @ main@main -> UnsafeEta +//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ main@main.sum@sum -> Pure +//│ deforest > call +@result @ main@main.sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ main@main.enum@enum -> Pure +//│ deforest > call -@result @ main@main.enum@enum -> Pure +//│ deforest > call >@result @ enum@enum -> Pure +//│ deforest > call >@result @ enum@enum -> Pure +//│ deforest > call >@result @ main@main.enum@enum -> Pure +//│ deforest > call >@result @ main@main.enum@enum -> Pure +//│ deforest > call enum@result @ -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ main@main -> UnsafeEta +//│ deforest > call enum@result @ main@main -> UnsafeEta +//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta +//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta +//│ deforest > call main@result @ -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ main@main -> UnsafeEta +//│ deforest > call sum@result @ main@main -> UnsafeEta +//│ deforest > call sum@result @ main@main.sum@sum -> UnsafeEta +//│ deforest > call sum@result @ main@main.sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > DeforestList⁰.this.Nil⁰ -> //│ deforest > match: ls⁰ @@ -80,6 +133,54 @@ module DeforestList with fun main() = DeforestList.sum(DeforestList.enum(3)) val res = DeforestList.sum(DeforestList.enum(100)) DeforestList.res + DeforestList.main() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta +//│ deforest > function helper#0 @ main@main.sum@sum -> UnsafeEta +//│ deforest > function helper#0 @ main@main.sum@sum -> UnsafeEta +//│ deforest > function helper#0 @ sum@sum -> UnsafeEta +//│ deforest > function helper#0 @ sum@sum -> UnsafeEta +//│ deforest > function main#0 @ main@main -> UnsafeEta +//│ deforest > function main#0 @ main@main -> UnsafeEta +//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ main@main.sum@sum -> Pure +//│ deforest > call +@result @ main@main.sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ main@main.enum@enum -> Pure +//│ deforest > call -@result @ main@main.enum@enum -> Pure +//│ deforest > call >@result @ enum@enum -> Pure +//│ deforest > call >@result @ enum@enum -> Pure +//│ deforest > call >@result @ main@main.enum@enum -> Pure +//│ deforest > call >@result @ main@main.enum@enum -> Pure +//│ deforest > call enum@result @ -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ main@main -> UnsafeEta +//│ deforest > call enum@result @ main@main -> UnsafeEta +//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta +//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta +//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta +//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta +//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta +//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta +//│ deforest > call helper@result @ sum@sum -> UnsafeEta +//│ deforest > call helper@result @ sum@sum -> UnsafeEta +//│ deforest > call helper@result @ sum@sum -> UnsafeEta +//│ deforest > call helper@result @ sum@sum -> UnsafeEta +//│ deforest > call main@result @ -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ main@main -> UnsafeEta +//│ deforest > call sum@result @ main@main -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > DeforestList¹.this.Nil¹ -> //│ deforest > match: ls¹ @@ -113,6 +214,13 @@ module MMM with fun f() = if A is A then y MMM.f() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > MMM⁰.this.A⁰ -> //│ deforest > match: scrut⁰ @@ -137,6 +245,11 @@ module M with if y is Y then x M.f(M.X) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > M¹.X⁰ -> //│ deforest > match: k⁰ @@ -164,6 +277,38 @@ module M with else C [M.f(3), M.g(true)] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ g@g -> UnsafeEta +//│ deforest > function f#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ g@g -> Pure +//│ deforest > call -@result @ g@g -> Pure +//│ deforest > call <@result @ f@f -> Pure +//│ deforest > call <@result @ f@f -> Pure +//│ deforest > call <@result @ g@g -> Pure +//│ deforest > call <@result @ g@g -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰(0) -> //│ deforest > match: scrut¹ @@ -203,6 +348,16 @@ private fun f(module I: O.I) = I.C(3) private fun g(x, module I: O.I) = if x is I.C(y) then y + 2 g(f(O.I), O.I) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > I⁰.C¹(3) -> //│ deforest > match: x¹ @@ -217,6 +372,16 @@ private fun f(module O: O) = O.I.C(3) private fun g(x, module O: O) = if x is O.I.C(y) then y + 2 g(f(O), O) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > O⁰.I¹.C¹(3) -> //│ deforest > match: x³ diff --git a/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls b/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls index c99a124325..739d8636ec 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls @@ -4,12 +4,25 @@ // Test: Deforestation with function of multiple parameter lists object A data class Pair(x, y) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< fun test(a)(b) = if a is Pair(x, y) then x + y + b test(Pair(1, 2))(3) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#1 @ test@test -> UnsafeEta +//│ deforest > function test#1 @ test@test -> UnsafeEta +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Pair⁰(1, 2) -> //│ deforest > match: a⁰ @@ -20,12 +33,23 @@ test(Pair(1, 2))(3) // Test: Deforestation with nested constructor calls and multiple param lists data class Box(v) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< fun unbox(b)(offset) = if b is Box(v) then v + offset unbox(Box(10))(5) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function unbox#0 @ unbox@unbox -> Pure +//│ deforest > function unbox#0 @ unbox@unbox -> Pure +//│ deforest > function unbox#1 @ unbox@unbox -> UnsafeEta +//│ deforest > function unbox#1 @ unbox@unbox -> UnsafeEta +//│ deforest > call +@result @ unbox@unbox -> Pure +//│ deforest > call +@result @ unbox@unbox -> Pure +//│ deforest > call unbox@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Box⁰(10) -> //│ deforest > match: b⁰ diff --git a/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls b/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls index 1deb2c2326..5dde7775d8 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls @@ -7,16 +7,22 @@ object C data class AA(x) data class BB(x) data class CC(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< object Nil data class (::) Cons(h, t) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< object None data class Some(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -34,6 +40,29 @@ fun g(x) = if x is AA then 0 let a = AA(AA(3)) f(a, 2) + g(a) + f(BB(3), 2) + f(AA(AA(4)), 5) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> //│ deforest > match: x⁰ @@ -58,6 +87,20 @@ fun f(x, y) = AA(m) then m n + 2 + y f(AA(AA(3)), 9) + f(AA(AA(4)), 10) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp¹) -> //│ deforest > match: x³ @@ -84,6 +127,13 @@ fun f(x) = AA(m) then m n + 2 f(AA(AA(3))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp³) -> //│ deforest > match: x⁴ @@ -102,6 +152,17 @@ fun f(x) = AA(AA(a)) then a t + 3 f(AA(AA(A))) + f(AA(AA(A))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁴) -> //│ deforest > match: x⁵ @@ -124,6 +185,11 @@ f(AA(AA(A))) + f(AA(AA(A))) fun c2(x) = if x is AA(AA(a)) then a c2(AA(AA(0))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁶) -> //│ deforest > match: x⁶ @@ -140,6 +206,11 @@ c2(AA(AA(0))) fun f(a) = if a is AA(BB(B)) then 3 f(AA(BB(B))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁷) -> //│ deforest > match: a³ @@ -162,6 +233,23 @@ fun test(x, y, z, i) = if x is BB(a2) then a2 - i m + n test(AA(1), AA(2), BB(3), 4) + test(AA(1), AA(2), BB(3), 4) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> //│ deforest > match: z⁰ @@ -198,6 +286,26 @@ fun f3(x) = if x is CC then "f3" + x.CC#x fun aa(x) = AA(x) let cc = CC("cc") f1(aa(BB(cc))) + f2(aa(BB(CC(0)))) + f3(cc) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function aa#0 @ aa@aa -> UnsafeEta +//│ deforest > function aa#0 @ aa@aa -> UnsafeEta +//│ deforest > function aa#0 @ aa@aa -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f3@f3 -> Pure +//│ deforest > call +@result @ f3@f3 -> Pure +//│ deforest > call aa@result @ -> UnsafeEta +//│ deforest > call aa@result @ -> UnsafeEta +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call f3@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x⁸) -> //│ deforest > match: x⁹ @@ -221,6 +329,13 @@ fun c(x, y) = if x is t + x.AA#x let y = A in c(AA(2), y) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> //│ deforest > match: x¹¹ @@ -240,6 +355,19 @@ fun c(x, y) = if x is fun c2(y) = if y is A then 3 let y = A in c(AA(2), y) + c2(y) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> //│ deforest > match: x¹² @@ -260,6 +388,21 @@ fun f(a) = if a is AA(AA) then "0" let p = AA(AA(AA("10"))) test(p) + f(p) + test(AA(A)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(A⁰) -> //│ deforest > match: x¹³ @@ -286,6 +429,20 @@ fun f(x, y) = AA then m + tmp.BB#x let aa = AA(3) f(aa, 3) + f(aa, 4) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(tmp⁸) -> //│ deforest > match: tmp⁹ @@ -327,6 +484,20 @@ fun test(n, p, q) = if q is AA(y) then k + y test(3, AA(2), AA(3)) + test(3, AA(2), AA(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(0) -> //│ deforest > match: scrut² @@ -367,6 +538,24 @@ fun test(n, p, q, a) = let a = A fun c(a) = if a is A then 0 test(1, AA(2), AA(3), a) + test(2, AA(2), AA(3), a) + c(a) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(3) -> //│ deforest > match: q¹ @@ -397,6 +586,26 @@ fun test(x, y, z, i) = m + n k + i test(AA(1), AA(2), BB(3), 4) + test(AA(1), AA(2), BB(3), 4) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> //│ deforest > match: z¹ @@ -432,6 +641,29 @@ fun test(x, y, z, i) = m + n k + i test(AA(1), AA(2), BB(3), 4) + test(AA(1), BB(2), BB(3), 4) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> //│ deforest > match: z² @@ -465,6 +697,28 @@ fun test(x) = fun c(x) = if x is AA then 0 fun p(x) = AA(x) test(p(BB(3))) + test(p(CC(3))) + c(p(A)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call test@result @ -> Pure +//│ deforest > call test@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x¹⁶) -> //│ deforest > match: x¹⁷ @@ -500,6 +754,26 @@ fun f(x, y, z, k) = if AA(3) is AA then m + k f(AA(3), 3, true, 10) + f(AA(5), 4, false, 20) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(tmp¹⁰) -> //│ deforest > match: tmp¹¹ @@ -552,6 +826,17 @@ fun f(a) = if a is AA(AA) then 0 let p = AA(AA(AA(10))) test(p) + f(p) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 15 @@ -571,6 +856,23 @@ fun test(a, b) = B then print("B") print(x) test(B, B) + test(A, A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call print@result @ test@test -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: a⁴ @@ -598,6 +900,22 @@ fun sum(ls) = if ls is Nil then 0 h :: t then h + sum(t) sum(prodDouble(4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function prodDouble#0 @ prodDouble@prodDouble -> UnsafeEta +//│ deforest > function prodDouble#0 @ prodDouble@prodDouble -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call -@result @ prodDouble@prodDouble -> Pure +//│ deforest > call -@result @ prodDouble@prodDouble -> Pure +//│ deforest > call prodDouble@result @ -> UnsafeEta +//│ deforest > call prodDouble@result @ prodDouble@prodDouble -> UnsafeEta +//│ deforest > call prodDouble@result @ prodDouble@prodDouble -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls⁰ @@ -623,6 +941,24 @@ fun cons(ls) = if ls is h1 :: h2 :: t then h1 + h2 + cons(t) _ then 0 cons(prod(4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function cons#0 @ cons@cons -> Pure +//│ deforest > function cons#0 @ cons@cons -> Pure +//│ deforest > function prod#0 @ prod@prod -> UnsafeEta +//│ deforest > function prod#0 @ prod@prod -> UnsafeEta +//│ deforest > call +@result @ cons@cons -> Pure +//│ deforest > call +@result @ cons@cons -> Pure +//│ deforest > call +@result @ cons@cons -> Pure +//│ deforest > call +@result @ cons@cons -> Pure +//│ deforest > call -@result @ prod@prod -> Pure +//│ deforest > call -@result @ prod@prod -> Pure +//│ deforest > call cons@result @ -> Pure +//│ deforest > call cons@result @ cons@cons -> Pure +//│ deforest > call cons@result @ cons@cons -> Pure +//│ deforest > call prod@result @ -> UnsafeEta +//│ deforest > call prod@result @ prod@prod -> UnsafeEta +//│ deforest > call prod@result @ prod@prod -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 10 diff --git a/hkmc2/shared/src/test/mlscript/deforest/recursive.mls b/hkmc2/shared/src/test/mlscript/deforest/recursive.mls index efb5813e30..043b8eff46 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/recursive.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/recursive.mls @@ -11,6 +11,8 @@ object A object B data class T(n, l, r) object L +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -22,6 +24,19 @@ fun map(f, ls_map) = if ls_map is Nil then Nil let c = Cons(1, Nil) in map(x => x + 1, c) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, Nil⁰) -> //│ deforest > match: ls_map⁰ @@ -38,6 +53,22 @@ fun map(f, ls_map) = if ls_map is Nil then Nil fun c(a) = Cons(a, Nil) map(x => x + 1, c(1)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁰, Nil⁰) -> //│ deforest > match: ls_map¹ @@ -54,6 +85,19 @@ fun map(ls, f) = if ls is Nil then Nil h :: t then f(h) :: map(t, f) map(1 :: 2 :: Nil, x => x + 1) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp⁰) -> //│ deforest > match: ls⁰ @@ -74,6 +118,24 @@ fun sum(ls) = if ls is h :: t then h + sum(t) fun enum(n) = if n > 0 then n :: enum(n - 1) else Nil sum(enum(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call >@result @ enum@enum -> Pure +//│ deforest > call >@result @ enum@enum -> Pure +//│ deforest > call enum@result @ -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(n⁰, tmp¹) -> //│ deforest > match: ls¹ @@ -90,6 +152,28 @@ fun map(ls, f) = if ls is Nil then Nil h :: t then f(h) :: map(t, f) map(map(id(1 :: 2 :: Nil), x => x + 1), x => x * 2) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call *@result @ lambda@lambda -> Pure +//│ deforest > call *@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls² @@ -106,6 +190,37 @@ fun map(f, ls) = if ls is h :: t then f(h) :: map(f, t) fun enum(a) = if a < 0 then Nil else a :: enum(a - 1) map(x => x + 1, map(x => x * 2, id(enum(3)))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function enum#0 @ enum@enum -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call *@result @ lambda@lambda -> Pure +//│ deforest > call *@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call -@result @ enum@enum -> Pure +//│ deforest > call <@result @ enum@enum -> Pure +//│ deforest > call <@result @ enum@enum -> Pure +//│ deforest > call enum@result @ -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call enum@result @ enum@enum -> UnsafeEta +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls³ @@ -129,6 +244,57 @@ fun cons1(a1) = if a1 is Nil then 1 h :: t then h + cons1(t) cons(f(0)) + cons1(f(1)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function cons#0 @ cons@cons -> UnsafeEta +//│ deforest > function cons#0 @ cons@cons -> UnsafeEta +//│ deforest > function cons1#0 @ cons1@cons1 -> UnsafeEta +//│ deforest > function cons1#0 @ cons1@cons1 -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ cons1@cons1 -> Pure +//│ deforest > call +@result @ cons1@cons1 -> Pure +//│ deforest > call +@result @ cons@cons -> Pure +//│ deforest > call +@result @ cons@cons -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ g@g -> Pure +//│ deforest > call -@result @ g@g -> Pure +//│ deforest > call cons1@result @ -> UnsafeEta +//│ deforest > call cons1@result @ cons1@cons1 -> UnsafeEta +//│ deforest > call cons1@result @ cons1@cons1 -> UnsafeEta +//│ deforest > call cons@result @ -> UnsafeEta +//│ deforest > call cons@result @ cons@cons -> UnsafeEta +//│ deforest > call cons@result @ cons@cons -> UnsafeEta +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ g@g -> UnsafeEta +//│ deforest > call equals@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: a1⁰ @@ -170,6 +336,24 @@ fun f1(ls1) = if ls1 is h :: t then h + f1(t) Nil then 2 f1(to(4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f1@result @ f1@f1 -> UnsafeEta +//│ deforest > call f1@result @ f1@f1 -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(n¹, tmp⁸) -> //│ deforest > match: ls1⁰ @@ -187,6 +371,27 @@ fun map(ls, f) = if ls is fun succ(x) = x + 1 fun double(x) = x * 2 map(map(1 :: 2 :: Nil, succ), double) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function double#0 @ double@double -> Pure +//│ deforest > function double#0 @ double@double -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function succ#0 @ succ@succ -> Pure +//│ deforest > function succ#0 @ succ@succ -> Pure +//│ deforest > call *@result @ double@double -> Pure +//│ deforest > call *@result @ double@double -> Pure +//│ deforest > call +@result @ succ@succ -> Pure +//│ deforest > call +@result @ succ@succ -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls⁴ @@ -217,6 +422,41 @@ fun f2(ls) = if ls is Nil then 3 fun wrap(n) = to(n) f1(wrap(4)) + f2(wrap(5)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ wrap@wrap.to@to -> UnsafeEta +//│ deforest > function to#0 @ wrap@wrap.to@to -> UnsafeEta +//│ deforest > function to#0 @ wrap@wrap.to@to -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ wrap@wrap.to@to -> Pure +//│ deforest > call -@result @ wrap@wrap.to@to -> Pure +//│ deforest > call -@result @ wrap@wrap.to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call >@result @ wrap@wrap.to@to -> Pure +//│ deforest > call >@result @ wrap@wrap.to@to -> Pure +//│ deforest > call >@result @ wrap@wrap.to@to -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ wrap@wrap -> UnsafeEta +//│ deforest > call to@result @ wrap@wrap -> UnsafeEta +//│ deforest > call to@result @ wrap@wrap -> UnsafeEta +//│ deforest > call to@result @ wrap@wrap.to@to -> UnsafeEta +//│ deforest > call to@result @ wrap@wrap.to@to -> UnsafeEta +//│ deforest > call to@result @ wrap@wrap.to@to -> UnsafeEta +//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls⁵ @@ -242,6 +482,49 @@ fun f2(ls, acc) = if ls is Nil then acc h :: t then f2(t, acc + h + 1) f1(to(4, Nil), 0) + f2(to(5, Nil), 0) + f1(to(6, Nil), 0) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call equals@result @ to@to -> UnsafeEta +//│ deforest > call equals@result @ to@to -> UnsafeEta +//│ deforest > call equals@result @ to@to -> UnsafeEta +//│ deforest > call equals@result @ to@to -> UnsafeEta +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f1@result @ f1@f1 -> UnsafeEta +//│ deforest > call f1@result @ f1@f1 -> UnsafeEta +//│ deforest > call f1@result @ f1@f1 -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call f2@result @ f2@f2 -> UnsafeEta +//│ deforest > call f2@result @ f2@f2 -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls⁷ @@ -272,6 +555,35 @@ fun succ(x) = x + 1 fun double(x) = x * 2 fun triple(x) = x * 3 map(map(map(1 :: 2 :: Nil, succ), double), triple) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function double#0 @ double@double -> Pure +//│ deforest > function double#0 @ double@double -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function succ#0 @ succ@succ -> Pure +//│ deforest > function succ#0 @ succ@succ -> Pure +//│ deforest > function triple#0 @ triple@triple -> Pure +//│ deforest > function triple#0 @ triple@triple -> Pure +//│ deforest > call *@result @ double@double -> Pure +//│ deforest > call *@result @ double@double -> Pure +//│ deforest > call *@result @ triple@triple -> Pure +//│ deforest > call *@result @ triple@triple -> Pure +//│ deforest > call +@result @ succ@succ -> Pure +//│ deforest > call +@result @ succ@succ -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls⁹ @@ -312,6 +624,40 @@ fun map1(f, ls_map1) = if ls_map1 is fun incr(x) = x + 1 fun double(x) = x * 2 map1(incr, map(double, id(mk(5)))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function double#0 @ double@double -> Pure +//│ deforest > function double#0 @ double@double -> Pure +//│ deforest > function incr#0 @ incr@incr -> Pure +//│ deforest > function incr#0 @ incr@incr -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map1#0 @ map1@map1 -> UnsafeEta +//│ deforest > function map1#0 @ map1@map1 -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > call *@result @ double@double -> Pure +//│ deforest > call *@result @ double@double -> Pure +//│ deforest > call +@result @ incr@incr -> Pure +//│ deforest > call +@result @ incr@incr -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call <@result @ mk@mk -> Pure +//│ deforest > call <@result @ mk@mk -> Pure +//│ deforest > call f@result @ map1@map1 -> Pure +//│ deforest > call f@result @ map1@map1 -> UnsafeEta +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call map1@result @ -> UnsafeEta +//│ deforest > call map1@result @ map1@map1 -> UnsafeEta +//│ deforest > call map1@result @ map1@map1 -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call mk@result @ -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(tmp¹⁶, tmp¹⁷) -> //│ deforest > match: ls_map1⁰ @@ -330,6 +676,24 @@ fun map(ls) = if ls is Nil then Nil h :: t then (h + 4) :: map(t) map(enumFromTo(1, 4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ map@map -> Pure +//│ deforest > call +@result @ map@map -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call enumFromTo@result @ -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a², tmp¹⁸) -> //│ deforest > match: ls¹⁰ @@ -346,6 +710,24 @@ fun sum(ls) = if ls is Nil then 0 h :: t then h + sum(t) sum(enumFromTo(1,10)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call enumFromTo@result @ -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a³, tmp¹⁹) -> //│ deforest > match: ls¹¹ @@ -363,6 +745,28 @@ fun map(f, ls) = Nil then Nil h :: t then f(h) :: map(f, t) map(x => x + 4, enumFromTo(1, 4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call enumFromTo@result @ -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁴, tmp²⁰) -> //│ deforest > match: ls¹² @@ -381,6 +785,34 @@ fun map(f, ls) = h :: t then f => f(h) :: map(f, t) )(f) map(x => x + 4, enumFromTo(1, 4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ map@map -> Pure +//│ deforest > function lambda#0 @ map@map -> Pure +//│ deforest > function lambda#0 @ map@map -> UnsafeEta +//│ deforest > function lambda#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call +@result @ lambda@lambda -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call enumFromTo@result @ -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call tmp@result @ map@map -> UnsafeEta +//│ deforest > call tmp@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁵, tmp²¹) -> //│ deforest > match: ls¹³ @@ -399,6 +831,24 @@ fun sum(ls, a) = if ls is Nil then a h :: t then sum(t, h + a) sum(enumFromTo(1, 10), 0) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call enumFromTo@result @ -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁶, tmp²²) -> //│ deforest > match: ls¹⁴ @@ -421,6 +871,34 @@ fun rev(xs_rev, acc) = if xs_rev is x :: xs then rev(xs, x :: acc) Nil then acc map(incr, rev(id(mk(5)), Nil)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function incr#0 @ incr@incr -> Pure +//│ deforest > function incr#0 @ incr@incr -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function rev#0 @ rev@rev -> UnsafeEta +//│ deforest > function rev#0 @ rev@rev -> UnsafeEta +//│ deforest > call +@result @ incr@incr -> Pure +//│ deforest > call +@result @ incr@incr -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call <@result @ mk@mk -> Pure +//│ deforest > call <@result @ mk@mk -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call mk@result @ -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call rev@result @ -> UnsafeEta +//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: xs_map⁰ @@ -443,6 +921,34 @@ fun rev(xs_rev, acc) = if xs_rev is x :: xs then rev(xs, x :: acc) Nil then acc rev(map(incr, id(mk(3))), Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function incr#0 @ incr@incr -> Pure +//│ deforest > function incr#0 @ incr@incr -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function rev#0 @ rev@rev -> UnsafeEta +//│ deforest > function rev#0 @ rev@rev -> UnsafeEta +//│ deforest > call +@result @ incr@incr -> Pure +//│ deforest > call +@result @ incr@incr -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call <@result @ mk@mk -> Pure +//│ deforest > call <@result @ mk@mk -> Pure +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call mk@result @ -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call rev@result @ -> UnsafeEta +//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: xs_rev⁰ @@ -456,6 +962,8 @@ rev(map(incr, id(mk(3))), Nil) data class Pair(a, b) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -469,6 +977,26 @@ fun pair_up(xs) = else Nil fun mk(n) = if n > 0 then (n - 1) :: n :: (n + 1) :: mk(n - 1) else Nil pair_up(mk(4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function pair_up#0 @ pair_up@pair_up -> UnsafeEta +//│ deforest > function pair_up#0 @ pair_up@pair_up -> UnsafeEta +//│ deforest > call +@result @ mk@mk -> Pure +//│ deforest > call +@result @ mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call >@result @ mk@mk -> Pure +//│ deforest > call >@result @ mk@mk -> Pure +//│ deforest > call mk@result @ -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call pair_up@result @ -> UnsafeEta +//│ deforest > call pair_up@result @ pair_up@pair_up -> UnsafeEta +//│ deforest > call pair_up@result @ pair_up@pair_up -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Cons( @@ -497,6 +1025,52 @@ fun flatten(ls_flatten) = if ls_flatten is Nil then Nil x :: xs then append(x, flatten(xs)) sum(flatten(id(mk2d(4)))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function append#0 @ append@append -> UnsafeEta +//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta +//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta +//│ deforest > function mk#0 @ mk2d@mk2d.mk@mk -> UnsafeEta +//│ deforest > function mk#0 @ mk2d@mk2d.mk@mk -> UnsafeEta +//│ deforest > function mk#0 @ mk@mk -> UnsafeEta +//│ deforest > function mk2d#0 @ mk2d@mk2d -> UnsafeEta +//│ deforest > function mk2d#0 @ mk2d@mk2d -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > function sum#0 @ sum@sum -> UnsafeEta +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call +@result @ sum@sum -> Pure +//│ deforest > call -@result @ mk2d@mk2d -> Pure +//│ deforest > call -@result @ mk2d@mk2d -> Pure +//│ deforest > call -@result @ mk2d@mk2d.mk@mk -> Pure +//│ deforest > call -@result @ mk2d@mk2d.mk@mk -> Pure +//│ deforest > call -@result @ mk@mk -> Pure +//│ deforest > call >@result @ mk2d@mk2d -> Pure +//│ deforest > call >@result @ mk2d@mk2d -> Pure +//│ deforest > call >@result @ mk2d@mk2d.mk@mk -> Pure +//│ deforest > call >@result @ mk2d@mk2d.mk@mk -> Pure +//│ deforest > call >@result @ mk@mk -> Pure +//│ deforest > call append@result @ append@append -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta +//│ deforest > call flatten@result @ -> UnsafeEta +//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta +//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call mk2d@result @ -> UnsafeEta +//│ deforest > call mk2d@result @ mk2d@mk2d -> UnsafeEta +//│ deforest > call mk2d@result @ mk2d@mk2d -> UnsafeEta +//│ deforest > call mk@result @ mk2d@mk2d -> UnsafeEta +//│ deforest > call mk@result @ mk2d@mk2d -> UnsafeEta +//│ deforest > call mk@result @ mk2d@mk2d.mk@mk -> UnsafeEta +//│ deforest > call mk@result @ mk2d@mk2d.mk@mk -> UnsafeEta +//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > call sum@result @ -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls_sum⁰ @@ -516,6 +1090,20 @@ fun rev(a, ys) = if ys is h :: t then rev(h :: a, t) Nil then a count(0, rev(Nil, 1 :: 2 :: Nil)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function count#0 @ count@count -> UnsafeEta +//│ deforest > function count#0 @ count@count -> UnsafeEta +//│ deforest > function rev#0 @ rev@rev -> UnsafeEta +//│ deforest > function rev#0 @ rev@rev -> UnsafeEta +//│ deforest > call +@result @ count@count -> Pure +//│ deforest > call +@result @ count@count -> Pure +//│ deforest > call count@result @ -> UnsafeEta +//│ deforest > call count@result @ count@count -> UnsafeEta +//│ deforest > call count@result @ count@count -> UnsafeEta +//│ deforest > call rev@result @ -> UnsafeEta +//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: xs⁰ @@ -545,6 +1133,13 @@ fun last(ls) = if ls is Nil then None let p = 1 :: 2 :: Nil last(p) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function last#0 @ last@last -> UnsafeEta +//│ deforest > function last#0 @ last@last -> UnsafeEta +//│ deforest > call last@result @ -> UnsafeEta +//│ deforest > call last@result @ last@last -> UnsafeEta +//│ deforest > call last@result @ last@last -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Some(2) @@ -557,6 +1152,17 @@ fun map(f, xs_map) = if xs_map is Nil then Nil x :: xs then f(x) :: map(f, xs) map(x => if x is A then 1 else 0, A :: B :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > call f@result @ map@map -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(A⁰, tmp²⁷) -> //│ deforest > match: xs_map¹ @@ -586,6 +1192,15 @@ fun c(x) = if x is c(r) L then L c(T(A, T(B, L, L), T(A, L, L))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call c@result @ c@c -> UnsafeEta +//│ deforest > call c@result @ c@c -> UnsafeEta +//│ deforest > call c@result @ c@c -> UnsafeEta +//│ deforest > call c@result @ c@c -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > T⁰(A⁰, tmp²⁸, tmp²⁹) -> //│ deforest > match: x⁴ @@ -627,6 +1242,17 @@ fun max(ms, m) = if ms is else max(t, m) Nil then m max(3 :: 2 :: 4 :: 1 :: 0 :: Nil, 0) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function max#0 @ max@max -> UnsafeEta +//│ deforest > function max#0 @ max@max -> UnsafeEta +//│ deforest > call >@result @ max@max -> Pure +//│ deforest > call >@result @ max@max -> Pure +//│ deforest > call max@result @ -> UnsafeEta +//│ deforest > call max@result @ max@max -> UnsafeEta +//│ deforest > call max@result @ max@max -> UnsafeEta +//│ deforest > call max@result @ max@max -> UnsafeEta +//│ deforest > call max@result @ max@max -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(3, tmp³⁰) -> //│ deforest > match: ms⁰ @@ -669,6 +1295,46 @@ fun last(ls_last) = Nil then None fun lastFilter(ls, f) = last(filter(ls, f)) lastFilter(id(1 :: 2 :: 3 :: 4 :: 5 :: Nil), x => (x % 2 == 0)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function filter#0 @ filter@filter -> UnsafeEta +//│ deforest > function filter#0 @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > function filter#0 @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > function go#0 @ last@last -> UnsafeEta +//│ deforest > function go#0 @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > function go#0 @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta +//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta +//│ deforest > function last#0 @ last@last -> UnsafeEta +//│ deforest > function last#0 @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > function last#0 @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > function lastFilter#0 @ lastFilter@lastFilter -> UnsafeEta +//│ deforest > function lastFilter#0 @ lastFilter@lastFilter -> UnsafeEta +//│ deforest > call %@result @ lambda@lambda -> Pure +//│ deforest > call %@result @ lambda@lambda -> Pure +//│ deforest > call equals@result @ lambda@lambda -> UnsafeEta +//│ deforest > call equals@result @ lambda@lambda -> UnsafeEta +//│ deforest > call f@result @ filter@filter -> UnsafeEta +//│ deforest > call f@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > call f@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > call filter@result @ filter@filter -> UnsafeEta +//│ deforest > call filter@result @ filter@filter -> UnsafeEta +//│ deforest > call filter@result @ lastFilter@lastFilter -> UnsafeEta +//│ deforest > call filter@result @ lastFilter@lastFilter -> UnsafeEta +//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta +//│ deforest > call go@result @ last@last -> UnsafeEta +//│ deforest > call go@result @ last@last -> UnsafeEta +//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call last@result @ lastFilter@lastFilter -> UnsafeEta +//│ deforest > call last@result @ lastFilter@lastFilter -> UnsafeEta +//│ deforest > call lastFilter@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = Some(4) @@ -678,6 +1344,32 @@ lastFilter(id(1 :: 2 :: 3 :: 4 :: 5 :: Nil), x => (x % 2 == 0)) fun g() = f() fun f() = g() + g() [f, g] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = [fun f, fun g] @@ -690,6 +1382,88 @@ fun h2() = g() fun g() = f() fun f() = h1() + h2() [h1, h2, g, f] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ h1@h1 -> Pure +//│ deforest > function f#0 @ h1@h1 -> Pure +//│ deforest > function f#0 @ h2@h2 -> Pure +//│ deforest > function f#0 @ h2@h2 -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ h1@h1 -> Pure +//│ deforest > function g#0 @ h1@h1 -> Pure +//│ deforest > function g#0 @ h2@h2 -> Pure +//│ deforest > function g#0 @ h2@h2 -> Pure +//│ deforest > function h1#0 @ f@f -> Pure +//│ deforest > function h1#0 @ f@f -> Pure +//│ deforest > function h1#0 @ g@g -> Pure +//│ deforest > function h1#0 @ g@g -> Pure +//│ deforest > function h1#0 @ h1@h1 -> Pure +//│ deforest > function h1#0 @ h1@h1 -> Pure +//│ deforest > function h1#0 @ h2@h2 -> Pure +//│ deforest > function h1#0 @ h2@h2 -> Pure +//│ deforest > function h2#0 @ f@f -> Pure +//│ deforest > function h2#0 @ f@f -> Pure +//│ deforest > function h2#0 @ g@g -> Pure +//│ deforest > function h2#0 @ g@g -> Pure +//│ deforest > function h2#0 @ h1@h1 -> Pure +//│ deforest > function h2#0 @ h1@h1 -> Pure +//│ deforest > function h2#0 @ h2@h2 -> Pure +//│ deforest > function h2#0 @ h2@h2 -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ h1@h1 -> Pure +//│ deforest > call f@result @ h1@h1 -> Pure +//│ deforest > call f@result @ h2@h2 -> Pure +//│ deforest > call f@result @ h2@h2 -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = [fun h1, fun h2, fun g, fun f] @@ -703,6 +1477,104 @@ fun h2() = g() + h1() fun g() = f() fun f() = h1() + h2() [h1, h2, g, f] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ h1@h1 -> Pure +//│ deforest > function f#0 @ h1@h1 -> Pure +//│ deforest > function f#0 @ h2@h2 -> Pure +//│ deforest > function f#0 @ h2@h2 -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ h1@h1 -> Pure +//│ deforest > function g#0 @ h1@h1 -> Pure +//│ deforest > function g#0 @ h2@h2 -> Pure +//│ deforest > function g#0 @ h2@h2 -> Pure +//│ deforest > function h1#0 @ f@f -> Pure +//│ deforest > function h1#0 @ f@f -> Pure +//│ deforest > function h1#0 @ g@g -> Pure +//│ deforest > function h1#0 @ g@g -> Pure +//│ deforest > function h1#0 @ h1@h1 -> Pure +//│ deforest > function h1#0 @ h1@h1 -> Pure +//│ deforest > function h1#0 @ h2@h2 -> Pure +//│ deforest > function h1#0 @ h2@h2 -> Pure +//│ deforest > function h2#0 @ f@f -> Pure +//│ deforest > function h2#0 @ f@f -> Pure +//│ deforest > function h2#0 @ g@g -> Pure +//│ deforest > function h2#0 @ g@g -> Pure +//│ deforest > function h2#0 @ h1@h1 -> Pure +//│ deforest > function h2#0 @ h1@h1 -> Pure +//│ deforest > function h2#0 @ h2@h2 -> Pure +//│ deforest > function h2#0 @ h2@h2 -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ h1@h1 -> Pure +//│ deforest > call f@result @ h1@h1 -> Pure +//│ deforest > call f@result @ h2@h2 -> Pure +//│ deforest > call f@result @ h2@h2 -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = [fun h1, fun h2, fun g, fun f] @@ -723,6 +1595,78 @@ fun g() = if false then h() + main() else 0 main +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ h@h -> Pure +//│ deforest > function f#0 @ main@main -> Pure +//│ deforest > function f#0 @ main@main -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ h@h -> Pure +//│ deforest > function g#0 @ main@main -> Pure +//│ deforest > function g#0 @ main@main -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ g@g -> Pure +//│ deforest > function h#0 @ h@h -> Pure +//│ deforest > function h#0 @ main@main -> Pure +//│ deforest > function h#0 @ main@main -> Pure +//│ deforest > function main#0 @ f@f -> Pure +//│ deforest > function main#0 @ g@g -> Pure +//│ deforest > function main#0 @ h@h -> Pure +//│ deforest > function main#0 @ main@main -> Pure +//│ deforest > function main#0 @ main@main -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ h@h -> Pure +//│ deforest > call +@result @ h@h -> Pure +//│ deforest > call +@result @ h@h -> Pure +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call +@result @ main@main -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ h@h -> Pure +//│ deforest > call f@result @ h@h -> Pure +//│ deforest > call f@result @ main@main -> Pure +//│ deforest > call f@result @ main@main -> Pure +//│ deforest > call f@result @ main@main -> Pure +//│ deforest > call f@result @ main@main -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ h@h -> Pure +//│ deforest > call g@result @ main@main -> Pure +//│ deforest > call g@result @ main@main -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ g@g -> Pure +//│ deforest > call h@result @ g@g -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > call h@result @ main@main -> Pure +//│ deforest > call h@result @ main@main -> Pure +//│ deforest > call h@result @ main@main -> Pure +//│ deforest > call h@result @ main@main -> Pure +//│ deforest > call main@result @ f@f -> Pure +//│ deforest > call main@result @ f@f -> Pure +//│ deforest > call main@result @ g@g -> Pure +//│ deforest > call main@result @ g@g -> Pure +//│ deforest > call main@result @ h@h -> Pure +//│ deforest > call main@result @ h@h -> Pure +//│ deforest > call main@result @ main@main -> Pure +//│ deforest > call main@result @ main@main -> Pure +//│ deforest > call main@result @ main@main -> Pure +//│ deforest > call main@result @ main@main -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = fun main @@ -740,6 +1684,80 @@ fun g1() = f() fun h2() = g2() fun g2() = f() f +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ g1@g1 -> UnsafeEta +//│ deforest > function f#0 @ g2@g2 -> UnsafeEta +//│ deforest > function f#0 @ h1@h1 -> UnsafeEta +//│ deforest > function f#0 @ h2@h2 -> UnsafeEta +//│ deforest > function g1#0 @ f@f -> UnsafeEta +//│ deforest > function g1#0 @ f@f -> UnsafeEta +//│ deforest > function g1#0 @ g1@g1 -> UnsafeEta +//│ deforest > function g1#0 @ g2@g2 -> UnsafeEta +//│ deforest > function g1#0 @ h1@h1 -> UnsafeEta +//│ deforest > function g1#0 @ h2@h2 -> UnsafeEta +//│ deforest > function g2#0 @ f@f -> UnsafeEta +//│ deforest > function g2#0 @ f@f -> UnsafeEta +//│ deforest > function g2#0 @ g1@g1 -> UnsafeEta +//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta +//│ deforest > function g2#0 @ h1@h1 -> UnsafeEta +//│ deforest > function g2#0 @ h2@h2 -> UnsafeEta +//│ deforest > function h1#0 @ f@f -> UnsafeEta +//│ deforest > function h1#0 @ f@f -> UnsafeEta +//│ deforest > function h1#0 @ g1@g1 -> UnsafeEta +//│ deforest > function h1#0 @ g2@g2 -> UnsafeEta +//│ deforest > function h1#0 @ h1@h1 -> UnsafeEta +//│ deforest > function h1#0 @ h2@h2 -> UnsafeEta +//│ deforest > function h2#0 @ f@f -> UnsafeEta +//│ deforest > function h2#0 @ f@f -> UnsafeEta +//│ deforest > function h2#0 @ g1@g1 -> UnsafeEta +//│ deforest > function h2#0 @ g2@g2 -> UnsafeEta +//│ deforest > function h2#0 @ h1@h1 -> UnsafeEta +//│ deforest > function h2#0 @ h2@h2 -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ g1@g1 -> Pure +//│ deforest > call +@result @ g2@g2 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ g1@g1 -> UnsafeEta +//│ deforest > call f@result @ g1@g1 -> UnsafeEta +//│ deforest > call f@result @ g2@g2 -> UnsafeEta +//│ deforest > call f@result @ g2@g2 -> UnsafeEta +//│ deforest > call f@result @ h1@h1 -> UnsafeEta +//│ deforest > call f@result @ h1@h1 -> UnsafeEta +//│ deforest > call f@result @ h2@h2 -> UnsafeEta +//│ deforest > call f@result @ h2@h2 -> UnsafeEta +//│ deforest > call g1@result @ f@f -> UnsafeEta +//│ deforest > call g1@result @ f@f -> UnsafeEta +//│ deforest > call g1@result @ g1@g1 -> UnsafeEta +//│ deforest > call g1@result @ g2@g2 -> UnsafeEta +//│ deforest > call g1@result @ h1@h1 -> UnsafeEta +//│ deforest > call g1@result @ h2@h2 -> UnsafeEta +//│ deforest > call g2@result @ f@f -> UnsafeEta +//│ deforest > call g2@result @ f@f -> UnsafeEta +//│ deforest > call g2@result @ g1@g1 -> UnsafeEta +//│ deforest > call g2@result @ g2@g2 -> UnsafeEta +//│ deforest > call g2@result @ h1@h1 -> UnsafeEta +//│ deforest > call g2@result @ h2@h2 -> UnsafeEta +//│ deforest > call h1@result @ f@f -> UnsafeEta +//│ deforest > call h1@result @ f@f -> UnsafeEta +//│ deforest > call h1@result @ g1@g1 -> UnsafeEta +//│ deforest > call h1@result @ g2@g2 -> UnsafeEta +//│ deforest > call h1@result @ h1@h1 -> UnsafeEta +//│ deforest > call h1@result @ h2@h2 -> UnsafeEta +//│ deforest > call h2@result @ f@f -> UnsafeEta +//│ deforest > call h2@result @ f@f -> UnsafeEta +//│ deforest > call h2@result @ g1@g1 -> UnsafeEta +//│ deforest > call h2@result @ g2@g2 -> UnsafeEta +//│ deforest > call h2@result @ h1@h1 -> UnsafeEta +//│ deforest > call h2@result @ h2@h2 -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: B⁰ @@ -763,6 +1781,104 @@ fun h2() = g() + h2() fun g() = f() fun f() = h1() + h2() [h1, h2, g, f] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ h1@h1 -> Pure +//│ deforest > function f#0 @ h1@h1 -> Pure +//│ deforest > function f#0 @ h2@h2 -> Pure +//│ deforest > function f#0 @ h2@h2 -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ h1@h1 -> Pure +//│ deforest > function g#0 @ h1@h1 -> Pure +//│ deforest > function g#0 @ h2@h2 -> Pure +//│ deforest > function g#0 @ h2@h2 -> Pure +//│ deforest > function h1#0 @ f@f -> Pure +//│ deforest > function h1#0 @ f@f -> Pure +//│ deforest > function h1#0 @ g@g -> Pure +//│ deforest > function h1#0 @ g@g -> Pure +//│ deforest > function h1#0 @ h1@h1 -> Pure +//│ deforest > function h1#0 @ h1@h1 -> Pure +//│ deforest > function h1#0 @ h2@h2 -> Pure +//│ deforest > function h1#0 @ h2@h2 -> Pure +//│ deforest > function h2#0 @ f@f -> Pure +//│ deforest > function h2#0 @ f@f -> Pure +//│ deforest > function h2#0 @ g@g -> Pure +//│ deforest > function h2#0 @ g@g -> Pure +//│ deforest > function h2#0 @ h1@h1 -> Pure +//│ deforest > function h2#0 @ h1@h1 -> Pure +//│ deforest > function h2#0 @ h2@h2 -> Pure +//│ deforest > function h2#0 @ h2@h2 -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h1@h1 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call +@result @ h2@h2 -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ h1@h1 -> Pure +//│ deforest > call f@result @ h1@h1 -> Pure +//│ deforest > call f@result @ h2@h2 -> Pure +//│ deforest > call f@result @ h2@h2 -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h1@h1 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call g@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ f@f -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ g@g -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h1@h1 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h1@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ f@f -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ g@g -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h1@h1 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = [fun h1, fun h2, fun g, fun f] @@ -771,6 +1887,24 @@ fun f() = h1() + h2() fun g() = f() fun f() = g() [g, f] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function f#0 @ g@g -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ f@f -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call f@result @ g@g -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > call g@result @ g@g -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = [fun g, fun f] @@ -781,6 +1915,20 @@ fun f() = g() fun g() = 0 fun f() = f() + g() [f, g] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function g#0 @ f@f.g@g -> Pure +//│ deforest > function g#0 @ f@f.g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = [fun f, fun g] @@ -797,6 +1945,120 @@ fun g4() = h(B) fun f() = [g1(), g2(), g3(), g4(), h(B)] f +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g1@g1 -> Pure +//│ deforest > function f#0 @ g2@g2 -> Pure +//│ deforest > function f#0 @ g3@g3 -> Pure +//│ deforest > function f#0 @ g4@g4 -> Pure +//│ deforest > function f#0 @ h@h -> Pure +//│ deforest > function g1#0 @ f@f -> Pure +//│ deforest > function g1#0 @ f@f -> Pure +//│ deforest > function g1#0 @ g1@g1 -> Pure +//│ deforest > function g1#0 @ g2@g2 -> Pure +//│ deforest > function g1#0 @ g3@g3 -> Pure +//│ deforest > function g1#0 @ g4@g4 -> Pure +//│ deforest > function g1#0 @ h@h -> Pure +//│ deforest > function g2#0 @ f@f -> Pure +//│ deforest > function g2#0 @ f@f -> Pure +//│ deforest > function g2#0 @ g1@g1 -> Pure +//│ deforest > function g2#0 @ g2@g2 -> Pure +//│ deforest > function g2#0 @ g3@g3 -> Pure +//│ deforest > function g2#0 @ g4@g4 -> Pure +//│ deforest > function g2#0 @ h@h -> Pure +//│ deforest > function g3#0 @ f@f -> Pure +//│ deforest > function g3#0 @ f@f -> Pure +//│ deforest > function g3#0 @ g1@g1 -> Pure +//│ deforest > function g3#0 @ g2@g2 -> Pure +//│ deforest > function g3#0 @ g3@g3 -> Pure +//│ deforest > function g3#0 @ g4@g4 -> Pure +//│ deforest > function g3#0 @ h@h -> Pure +//│ deforest > function g4#0 @ f@f -> Pure +//│ deforest > function g4#0 @ f@f -> Pure +//│ deforest > function g4#0 @ g1@g1 -> Pure +//│ deforest > function g4#0 @ g2@g2 -> Pure +//│ deforest > function g4#0 @ g3@g3 -> Pure +//│ deforest > function g4#0 @ g4@g4 -> Pure +//│ deforest > function g4#0 @ h@h -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ g1@g1 -> Pure +//│ deforest > function h#0 @ g2@g2 -> Pure +//│ deforest > function h#0 @ g3@g3 -> Pure +//│ deforest > function h#0 @ g4@g4 -> Pure +//│ deforest > function h#0 @ h@h -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g1@g1 -> Pure +//│ deforest > call f@result @ g2@g2 -> Pure +//│ deforest > call f@result @ g3@g3 -> Pure +//│ deforest > call f@result @ g4@g4 -> Pure +//│ deforest > call f@result @ h@h -> Pure +//│ deforest > call g1@result @ f@f -> Pure +//│ deforest > call g1@result @ f@f -> Pure +//│ deforest > call g1@result @ g1@g1 -> Pure +//│ deforest > call g1@result @ g2@g2 -> Pure +//│ deforest > call g1@result @ g3@g3 -> Pure +//│ deforest > call g1@result @ g4@g4 -> Pure +//│ deforest > call g1@result @ h@h -> Pure +//│ deforest > call g2@result @ f@f -> Pure +//│ deforest > call g2@result @ f@f -> Pure +//│ deforest > call g2@result @ g1@g1 -> Pure +//│ deforest > call g2@result @ g2@g2 -> Pure +//│ deforest > call g2@result @ g3@g3 -> Pure +//│ deforest > call g2@result @ g4@g4 -> Pure +//│ deforest > call g2@result @ h@h -> Pure +//│ deforest > call g3@result @ f@f -> Pure +//│ deforest > call g3@result @ f@f -> Pure +//│ deforest > call g3@result @ g1@g1 -> Pure +//│ deforest > call g3@result @ g2@g2 -> Pure +//│ deforest > call g3@result @ g3@g3 -> Pure +//│ deforest > call g3@result @ g4@g4 -> Pure +//│ deforest > call g3@result @ h@h -> Pure +//│ deforest > call g4@result @ f@f -> Pure +//│ deforest > call g4@result @ f@f -> Pure +//│ deforest > call g4@result @ g1@g1 -> Pure +//│ deforest > call g4@result @ g2@g2 -> Pure +//│ deforest > call g4@result @ g3@g3 -> Pure +//│ deforest > call g4@result @ g4@g4 -> Pure +//│ deforest > call g4@result @ h@h -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ g1@g1 -> Pure +//│ deforest > call h@result @ g1@g1 -> Pure +//│ deforest > call h@result @ g1@g1 -> Pure +//│ deforest > call h@result @ g1@g1 -> Pure +//│ deforest > call h@result @ g1@g1 -> Pure +//│ deforest > call h@result @ g2@g2 -> Pure +//│ deforest > call h@result @ g2@g2 -> Pure +//│ deforest > call h@result @ g2@g2 -> Pure +//│ deforest > call h@result @ g2@g2 -> Pure +//│ deforest > call h@result @ g2@g2 -> Pure +//│ deforest > call h@result @ g3@g3 -> Pure +//│ deforest > call h@result @ g3@g3 -> Pure +//│ deforest > call h@result @ g3@g3 -> Pure +//│ deforest > call h@result @ g3@g3 -> Pure +//│ deforest > call h@result @ g3@g3 -> Pure +//│ deforest > call h@result @ g4@g4 -> Pure +//│ deforest > call h@result @ g4@g4 -> Pure +//│ deforest > call h@result @ g4@g4 -> Pure +//│ deforest > call h@result @ g4@g4 -> Pure +//│ deforest > call h@result @ g4@g4 -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: x⁵ @@ -871,6 +2133,53 @@ fun g2() = h(B) fun f() = [g1(), g2()] f +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ g1@g1 -> Pure +//│ deforest > function f#0 @ g2@g2 -> Pure +//│ deforest > function f#0 @ h@h -> Pure +//│ deforest > function g1#0 @ f@f -> Pure +//│ deforest > function g1#0 @ f@f -> Pure +//│ deforest > function g1#0 @ g1@g1 -> Pure +//│ deforest > function g1#0 @ g2@g2 -> Pure +//│ deforest > function g1#0 @ h@h -> Pure +//│ deforest > function g2#0 @ f@f -> Pure +//│ deforest > function g2#0 @ f@f -> Pure +//│ deforest > function g2#0 @ g1@g1 -> Pure +//│ deforest > function g2#0 @ g2@g2 -> Pure +//│ deforest > function g2#0 @ h@h -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ g1@g1 -> Pure +//│ deforest > function h#0 @ g2@g2 -> Pure +//│ deforest > function h#0 @ h@h -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ g1@g1 -> Pure +//│ deforest > call f@result @ g2@g2 -> Pure +//│ deforest > call f@result @ h@h -> Pure +//│ deforest > call g1@result @ f@f -> Pure +//│ deforest > call g1@result @ f@f -> Pure +//│ deforest > call g1@result @ g1@g1 -> Pure +//│ deforest > call g1@result @ g2@g2 -> Pure +//│ deforest > call g1@result @ h@h -> Pure +//│ deforest > call g2@result @ f@f -> Pure +//│ deforest > call g2@result @ f@f -> Pure +//│ deforest > call g2@result @ g1@g1 -> Pure +//│ deforest > call g2@result @ g2@g2 -> Pure +//│ deforest > call g2@result @ h@h -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ g1@g1 -> Pure +//│ deforest > call h@result @ g1@g1 -> Pure +//│ deforest > call h@result @ g2@g2 -> Pure +//│ deforest > call h@result @ g2@g2 -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > call h@result @ h@h -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: x⁶ @@ -902,6 +2211,32 @@ fun f() = else f() [() => h(B), () => h(B), () => h(B), () => h(B), h(B)] f +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > function lambda#0 @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call f@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: x⁷ diff --git a/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls b/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls index 3c5c9ec64a..47f2cf51e0 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls @@ -14,6 +14,11 @@ class Store(n) with AA(x) then x + nn val store = Store(1) store.foo(AA(4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(Store⁰.this.n⁰) -> //│ deforest > match: scrut⁰ @@ -38,6 +43,11 @@ class Store(n) with AA(x) then x + n val store = Store(1) store.foo(AA(4)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(Store¹.this.n¹) -> //│ deforest > match: scrut¹ @@ -62,6 +72,15 @@ fun classMethodSibling() = if AA(1) is AA(x) then x + store.get() classMethodSibling() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function classMethodSibling#0 @ classMethodSibling@classMethodSibling -> UnsafeEta +//│ deforest > function classMethodSibling#0 @ classMethodSibling@classMethodSibling -> UnsafeEta +//│ deforest > call +@result @ classMethodSibling@classMethodSibling -> Pure +//│ deforest > call +@result @ classMethodSibling@classMethodSibling -> Pure +//│ deforest > call classMethodSibling@result @ -> UnsafeEta +//│ deforest > call get@result @ classMethodSibling@classMethodSibling -> UnsafeEta +//│ deforest > call get@result @ classMethodSibling@classMethodSibling -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut² @@ -81,6 +100,9 @@ let r = if AA(1) is AA(x) then x + r!a +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call +@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut³ @@ -96,6 +118,9 @@ if AA(1) is AA(x) then let xs = [0, 1] x + xs!1 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call +@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut⁴ @@ -113,6 +138,13 @@ fun nestedClass() = if AA(1) is AA(x) then x nestedClass() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function nestedClass#0 @ nestedClass@nestedClass -> UnsafeEta +//│ deforest > function nestedClass#0 @ nestedClass@nestedClass -> UnsafeEta +//│ deforest > call get@result @ nestedClass@nestedClass -> UnsafeEta +//│ deforest > call get@result @ nestedClass@nestedClass -> UnsafeEta +//│ deforest > call nestedClass@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut⁵ @@ -132,6 +164,10 @@ fun loopSibling() = while false do if AA(1) is AA(x) then print(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function loopSibling#0 @ loopSibling@loopSibling -> UnsafeEta +//│ deforest > call print@result @ loopSibling@loopSibling -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut⁶ @@ -152,6 +188,13 @@ class C(n) with res let c = C(1) c.get() + c.get() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call get@result @ -> UnsafeEta +//│ deforest > call get@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut⁷ @@ -169,6 +212,13 @@ module M with if AA(1) is AA(a) then a + _private M.f() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut⁸ @@ -191,6 +241,18 @@ module M with if AA(1) is AA(a) then a + g() M.MM.f() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f.g@g -> Pure +//│ deforest > function g#0 @ f@f.g@g -> Pure +//│ deforest > function g#0 @ g@g -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > call g@result @ f@f -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> //│ deforest > match: scrut⁹ diff --git a/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls b/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls index 8a47163fbc..503e818e34 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls @@ -6,16 +6,22 @@ object B object C data class AA(x) data class BB(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< object Nil data class Cons(h, t) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< object None data class Some(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -28,6 +34,11 @@ fun c(x) = if x is if A is A then x.AA#x c(AA(2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: A⁰ @@ -46,6 +57,11 @@ fun c(x, y) = if x is if y is A then x.AA#x c(AA(2), A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: y⁰ @@ -64,6 +80,14 @@ fun c(x, y) = if x is A then x.AA#x fun p() = AA(2) c(p(), A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: y¹ @@ -84,6 +108,16 @@ fun c(x, y) = if x is a + x.AA#x fun p() = AA(2) c(p(), A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: y² @@ -103,6 +137,21 @@ fun g(x) = if x is AA(b) then f(b) A then 42 f(AA(AA(AA(AA(AA(A)))))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> //│ deforest > match: x⁵ @@ -128,6 +177,11 @@ f(AA(AA(AA(AA(AA(A)))))) fun f(x) = if x is AA(AA(a)) then a f(AA(AA(A))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁴) -> //│ deforest > match: x⁷ @@ -143,6 +197,14 @@ fun f(x) = if x is AA(AA(a)) then a fun p() = AA(AA(A)) f(p()) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁵) -> //│ deforest > match: x⁸ @@ -163,6 +225,13 @@ fun c(x, y) = A then x.AA#x t + y c(AA(2), 10) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: A⁰ diff --git a/hkmc2/shared/src/test/mlscript/deforest/simple.mls b/hkmc2/shared/src/test/mlscript/deforest/simple.mls index d43fcd646b..5d0750cdc5 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/simple.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/simple.mls @@ -15,6 +15,8 @@ object None data class Some(value) data object Nil data class (::) Cons(h, t) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -30,6 +32,19 @@ fun test(x) = AA(AA(v)) then v y + 1 + 2 + 3 + 4 test(AA(AA(10))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> //│ deforest > match: x⁰ @@ -47,6 +62,8 @@ let x = if true then A else B in... if x is A then 1 B then 2 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: x¹ @@ -60,6 +77,8 @@ let x = if true then AA(A) else BB(B) in... if x is AA(x) then x BB(x) then x +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(B⁰) -> //│ deforest > match: x² @@ -79,6 +98,13 @@ let x = if true then AA(A) else BB(B) in... if x is AA(x) then f(x) BB(x) then f(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(B⁰) -> //│ deforest > match: x³ @@ -108,6 +134,14 @@ let x = if true then AA(A) else BB(B) in... if x is AA then f1(x.AA#aa) BB then f2(x.BB#bb) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(B⁰) -> //│ deforest > match: x⁴ @@ -129,6 +163,14 @@ fun c(x) = if x is AA(x) then x BB(x) then x c(g(true)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(11) -> //│ deforest > match: x⁵ @@ -150,6 +192,8 @@ if x is B then 3 if x is B then 2 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 2 @@ -164,6 +208,8 @@ if x is A then 1 if y is B then 2 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: y⁰ @@ -181,6 +227,17 @@ fun c(a) = print(x) x c(A) + c(B) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call print@result @ c@c -> UnsafeEta +//│ deforest > call print@result @ c@c -> UnsafeEta +//│ deforest > call print@result @ c@c -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: a³ @@ -201,6 +258,13 @@ fun c(x) = AA then 2 n + t c(AA(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 5 @@ -212,6 +276,11 @@ fun f(a, b) = if a is A then if b is B then 3 f(A, B) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: a⁴ @@ -225,6 +294,17 @@ f(A, B) fun f(x) = if x is Some then if x.Some#value > 1 then f(Some(x.Some#value - 1)) else 0 f(Some(2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call >@result @ f@f -> Pure +//│ deforest > call >@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Some⁰(tmp¹) -> //│ deforest > match: x⁷ @@ -246,6 +326,8 @@ if x is A then 1 if y is B then 2 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: y¹ @@ -263,6 +345,45 @@ fun f(x, y) = BBB(n, m) then m + 1 - n a + 3 f(AAA(1, 3), 1) + f(BBB(2, 3), 2) + f(AAA(3, 2), 4) + f(BBB(4, 6), 0) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BBB⁰(4, 6) -> //│ deforest > match: x⁹ @@ -293,6 +414,23 @@ fun c2(x) = if x is AA then x.AA#aa fun p(a) = c1(a) + c2(a) p(AA(1)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ p@p.c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ p@p.c1@c1 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ p@p.c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ p@p.c2@c2 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ p@p -> Pure +//│ deforest > call +@result @ p@p -> Pure +//│ deforest > call c1@result @ p@p -> UnsafeEta +//│ deforest > call c1@result @ p@p -> UnsafeEta +//│ deforest > call c2@result @ p@p -> UnsafeEta +//│ deforest > call c2@result @ p@p -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: A⁰ @@ -311,6 +449,11 @@ fun c(x, y) = if x is if y is A then a c(AA(2), A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: y⁴ @@ -328,6 +471,40 @@ fun f(x, y) = CCC(n) then n + 1 a + 3 f(AAA(1, 3), 1) + f(CCC(2), 2) + f(AAA(3, 2), 4) + f(CCC(4), 0) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > CCC⁰(4) -> //│ deforest > match: x¹³ @@ -356,6 +533,29 @@ fun f(x, y) = CCC(n) then n + 1 a + 3 f(AAA(1, 3), 1) + f(CCC(2), 2) + f(AAA(3, 2), 4) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AAA⁰(3, 2) -> //│ deforest > match: x¹⁴ @@ -375,6 +575,13 @@ fun c(x, m) = if x is AA(n) then n + 1 else m c(BB(3), 0) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> Pure +//│ deforest > function c#0 @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call +@result @ c@c -> Pure +//│ deforest > call c@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> //│ deforest > match: x¹⁵ @@ -390,6 +597,19 @@ fun f(x) = if x is fun g(b) = if b is AA(a) then a + 1 f(AA(AA(0))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f.g@g -> UnsafeEta +//│ deforest > function g#0 @ f@f.g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call +@result @ f@f.g@g -> Pure +//│ deforest > call +@result @ f@f.g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp²) -> //│ deforest > match: x¹⁶ @@ -405,6 +625,11 @@ f(AA(AA(0))) :expect 3 fun f(x) = x.AA#aa.AA#aa f(AA(AA(3))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > call f@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp³) -> //│ deforest > select: aa @@ -431,6 +656,69 @@ fun outer2(x, y, z) = t + y let p = AA(AA(3)) outer1(p, 1, 2) + outer2(p, 3, 4) + inner(AA(5), 6) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function inner#0 @ inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function outer1#0 @ outer1@outer1 -> UnsafeEta +//│ deforest > function outer1#0 @ outer1@outer1 -> UnsafeEta +//│ deforest > function outer2#0 @ outer2@outer2 -> UnsafeEta +//│ deforest > function outer2#0 @ outer2@outer2 -> UnsafeEta +//│ deforest > call *@result @ inner@inner -> Pure +//│ deforest > call *@result @ inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ inner@inner -> Pure +//│ deforest > call +@result @ inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1 -> Pure +//│ deforest > call +@result @ outer1@outer1 -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2 -> Pure +//│ deforest > call +@result @ outer2@outer2 -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ inner@inner -> Pure +//│ deforest > call -@result @ inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call inner@result @ -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call outer1@result @ -> UnsafeEta +//│ deforest > call outer2@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(5) -> //│ deforest > match: x¹⁷ @@ -444,6 +732,15 @@ outer1(p, 1, 2) + outer2(p, 3, 4) + inner(AA(5), 6) fun mapHead(f, x) = if x is AAA(h, t) then f(h) mapHead(x => x, AAA(1, AAA(2, None))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function lambda#0 @ lambda@lambda -> Pure +//│ deforest > function mapHead#0 @ mapHead@mapHead -> UnsafeEta +//│ deforest > function mapHead#0 @ mapHead@mapHead -> UnsafeEta +//│ deforest > call f@result @ mapHead@mapHead -> Pure +//│ deforest > call f@result @ mapHead@mapHead -> UnsafeEta +//│ deforest > call mapHead@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AAA⁰(1, tmp⁴) -> //│ deforest > match: x¹⁸ @@ -459,6 +756,9 @@ if A is A then k = 3 k + 2 +//│ deforest > >>> effect-analysis results >>> +//│ deforest > call +@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: A⁰ @@ -471,6 +771,14 @@ fun test(a) = if a is AA then 1 else 2 test(B) + test(C) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call test@result @ -> Pure +//│ deforest > call test@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > C⁰ -> //│ deforest > match: a⁵ @@ -491,6 +799,17 @@ fun test(x, y, z) = if x is AA(a2) then a2 - z m + n test(AA(1), AA(2), AA(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> //│ deforest > match: y⁵ @@ -511,6 +830,23 @@ fun test(x) = t(123).AA#aa + 5 * 4 - 3 + 2 - 1 let p = if true then AA(CCC(AA)) else BB(CCC(AA)) in... test(p) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call id@result @ test@test -> UnsafeEta +//│ deforest > call id@result @ test@test -> UnsafeEta +//│ deforest > call t@result @ test@test -> UnsafeEta +//│ deforest > call t@result @ test@test -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(tmp⁵) -> //│ deforest > match: x²⁰ @@ -538,6 +874,22 @@ fun test(x, y) = t(123).CCC#c + 5 * 4 - 3 + 2 - 1 let p = if true then AA(CCC) else BB(CCC) in... test(p, id(CCC(123))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > call t@result @ test@test -> UnsafeEta +//│ deforest > call t@result @ test@test -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(CCC⁰) -> //│ deforest > match: x²¹ @@ -554,6 +906,15 @@ test(p, id(CCC(123))) fun f(x) = if x is A then 1 f(id(A)) + f(A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: x²² @@ -598,6 +959,14 @@ fun g(x) = if x is AA then A BB then B f(g(AA(1))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: x²³ @@ -614,6 +983,11 @@ fun f(a, b) = if a is A and b is B then 1 else 0 f(A, B) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > call f@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: a⁶ @@ -633,6 +1007,27 @@ fun c2(x) = if x is AA(i) then i A then 0 c1(app(AA)) + c1(AA(2)) + c2(AA(3)) + c2(A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function app#0 @ app@app -> UnsafeEta +//│ deforest > function app#0 @ app@app -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function identity#0 @ identity@identity -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call app@result @ -> UnsafeEta +//│ deforest > call c1@result @ -> UnsafeEta +//│ deforest > call c1@result @ -> UnsafeEta +//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > call f@result @ app@app -> UnsafeEta +//│ deforest > call f@result @ app@app -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: x²⁵ @@ -655,6 +1050,30 @@ fun c(x) = if x is else throw (if A is A then Error("e1") else Error("e2")) print(c(p(true)) + c(p(false))) c(B) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call Error@result @ c@c -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call print@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: A⁰ @@ -687,6 +1106,13 @@ c(B) fun f(a, b) = if a is AA(x) then x + b.BB#bb f(AA(1), BB(2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call +@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(2) -> //│ deforest > select: bb @@ -702,6 +1128,15 @@ f(AA(1), BB(2)) fun g(k, x) = if k is A then x.AA#aa + x.AA#aa + x.AA#aa g(A, AA(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call +@result @ g@g -> Pure +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: k⁰ @@ -728,6 +1163,83 @@ fun outer2(x, y)(z) = t + y let p = AA(AA(3)) outer1(p)(1, 2) + outer2(p, 3)(4) + inner(AA(5))(6) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function inner#0 @ inner@inner -> Pure +//│ deforest > function inner#0 @ inner@inner -> Pure +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure +//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure +//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure +//│ deforest > function inner#1 @ inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta +//│ deforest > function outer1#0 @ outer1@outer1 -> Pure +//│ deforest > function outer1#0 @ outer1@outer1 -> Pure +//│ deforest > function outer1#1 @ outer1@outer1 -> UnsafeEta +//│ deforest > function outer1#1 @ outer1@outer1 -> UnsafeEta +//│ deforest > function outer2#0 @ outer2@outer2 -> Pure +//│ deforest > function outer2#0 @ outer2@outer2 -> Pure +//│ deforest > function outer2#1 @ outer2@outer2 -> UnsafeEta +//│ deforest > function outer2#1 @ outer2@outer2 -> UnsafeEta +//│ deforest > call *@result @ inner@inner -> Pure +//│ deforest > call *@result @ inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ inner@inner -> Pure +//│ deforest > call +@result @ inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1 -> Pure +//│ deforest > call +@result @ outer1@outer1 -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2 -> Pure +//│ deforest > call +@result @ outer2@outer2 -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ inner@inner -> Pure +//│ deforest > call -@result @ inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure +//│ deforest > call inner@result @ -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta +//│ deforest > call outer1@result @ -> UnsafeEta +//│ deforest > call outer2@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(5) -> //│ deforest > match: x²⁷ @@ -745,6 +1257,11 @@ fun f(x) = if x is AA then if x.AA#aa is AA then x.AA#aa.AA#aa f(AA(AA(3))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁷) -> //│ deforest > match: x²⁸ @@ -761,6 +1278,20 @@ fun id(x) = x fun f1(a1) = if a1 is AA then 1 fun f2(a2) = if a2 is AA then 2 f1(id(AA(1))) + f2(id(AA(2))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function id#0 @ id@id -> Pure +//│ deforest > function id#0 @ id@id -> Pure +//│ deforest > function id#0 @ id@id -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call id@result @ -> Pure +//│ deforest > call id@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> //│ deforest > match: a2⁰ @@ -778,6 +1309,11 @@ fun c1(x) = if x is if t is Nil then 0 c1(1 :: Nil) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > call c1@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, Nil⁰) -> //│ deforest > match: x²⁹ @@ -801,6 +1337,25 @@ fun apply(f) = let inner = AA(0) f(AA(inner)) apply(f) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function apply#0 @ apply@apply -> UnsafeEta +//│ deforest > function apply#0 @ apply@apply -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function g1#0 @ f@f.g1@g1 -> UnsafeEta +//│ deforest > function g1#0 @ f@f.g1@g1 -> UnsafeEta +//│ deforest > function g1#0 @ g1@g1 -> UnsafeEta +//│ deforest > function g2#0 @ f@f.g2@g2 -> UnsafeEta +//│ deforest > function g2#0 @ f@f.g2@g2 -> UnsafeEta +//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta +//│ deforest > call apply@result @ -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > call g1@result @ f@f -> UnsafeEta +//│ deforest > call g1@result @ f@f -> UnsafeEta +//│ deforest > call g2@result @ f@f -> UnsafeEta +//│ deforest > call g2@result @ f@f -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(inner⁰) -> //│ deforest > match: x³⁰ @@ -818,6 +1373,36 @@ fun wrap(x) = wrap1(x) fun f1(a1) = if a1 is AA then 1 fun f2(a2) = if a2 is AA then 2 f1(wrap(1)) + f2(wrap(2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap1@wrap1.p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap@wrap.wrap1@wrap1.p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap@wrap.wrap1@wrap1.p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap@wrap.wrap1@wrap1.p@p -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > function wrap1#0 @ wrap1@wrap1 -> UnsafeEta +//│ deforest > function wrap1#0 @ wrap@wrap.wrap1@wrap1 -> UnsafeEta +//│ deforest > function wrap1#0 @ wrap@wrap.wrap1@wrap1 -> UnsafeEta +//│ deforest > function wrap1#0 @ wrap@wrap.wrap1@wrap1 -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call p@result @ wrap1@wrap1 -> UnsafeEta +//│ deforest > call p@result @ wrap@wrap.wrap1@wrap1 -> UnsafeEta +//│ deforest > call p@result @ wrap@wrap.wrap1@wrap1 -> UnsafeEta +//│ deforest > call p@result @ wrap@wrap.wrap1@wrap1 -> UnsafeEta +//│ deforest > call wrap1@result @ wrap@wrap -> UnsafeEta +//│ deforest > call wrap1@result @ wrap@wrap -> UnsafeEta +//│ deforest > call wrap1@result @ wrap@wrap -> UnsafeEta +//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³¹) -> //│ deforest > match: a2¹ @@ -832,6 +1417,30 @@ fun p1(x) = p2(x) fun p2(x) = if x == 0 then AA(x) else p1(x - 1) fun c(a) = if a is AA(x) then x c(p1(3)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function p1#0 @ p1@p1 -> UnsafeEta +//│ deforest > function p1#0 @ p1@p1 -> UnsafeEta +//│ deforest > function p1#0 @ p2@p2 -> UnsafeEta +//│ deforest > function p2#0 @ p1@p1 -> UnsafeEta +//│ deforest > function p2#0 @ p1@p1 -> UnsafeEta +//│ deforest > function p2#0 @ p2@p2 -> UnsafeEta +//│ deforest > call -@result @ p1@p1 -> Pure +//│ deforest > call -@result @ p1@p1 -> Pure +//│ deforest > call -@result @ p2@p2 -> Pure +//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > call equals@result @ p1@p1 -> UnsafeEta +//│ deforest > call equals@result @ p1@p1 -> UnsafeEta +//│ deforest > call equals@result @ p2@p2 -> UnsafeEta +//│ deforest > call p1@result @ -> UnsafeEta +//│ deforest > call p1@result @ p1@p1 -> UnsafeEta +//│ deforest > call p1@result @ p1@p1 -> UnsafeEta +//│ deforest > call p1@result @ p2@p2 -> UnsafeEta +//│ deforest > call p2@result @ p1@p1 -> UnsafeEta +//│ deforest > call p2@result @ p1@p1 -> UnsafeEta +//│ deforest > call p2@result @ p2@p2 -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³²) -> //│ deforest > match: a⁸ @@ -854,6 +1463,38 @@ fun g(b) = else C [f(3), g(true)] +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ g@g -> UnsafeEta +//│ deforest > function f#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ g@g -> Pure +//│ deforest > call -@result @ g@g -> Pure +//│ deforest > call <@result @ f@f -> Pure +//│ deforest > call <@result @ f@f -> Pure +//│ deforest > call <@result @ g@g -> Pure +//│ deforest > call <@result @ g@g -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(0) -> //│ deforest > match: scrut⁰ @@ -888,6 +1529,21 @@ fun f(ls) = if ls is [] then fun h(z) = if z > 0 then h(z - 1) else y h(3) f([]) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call >@result @ f@f -> Pure +//│ deforest > call >@result @ f@f -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [] -> //│ deforest > match: ls⁰ @@ -899,6 +1555,13 @@ f([]) fun f(x, b) = if x is Nil then if b then f(Nil, false) else 0 f(Nil, false) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: x³³ @@ -917,6 +1580,17 @@ fun test() = AA(x) then x a + b test() + test() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 4 @@ -927,6 +1601,20 @@ fun p(d) = AA(3) fun c1(x) = if x is AA then 1 fun c2(x) = if x is AA then 2 c1(p(1)) + c2(p(2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call c1@result @ -> UnsafeEta +//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(3) -> //│ deforest > match: x³⁴ @@ -944,6 +1632,38 @@ fun f3(a3) = if a3 is AA(aa) then aa fun f4(a4) = if a4 is AA(aa) then aa fun f5(a5) = if a5 is AA(aa) then aa f1(p(1)) + f2(p(2)) + f3(p(3)) + f4(p(4)) + f5(p(5)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta +//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta +//│ deforest > function f5#0 @ f5@f5 -> UnsafeEta +//│ deforest > function f5#0 @ f5@f5 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call f3@result @ -> UnsafeEta +//│ deforest > call f4@result @ -> UnsafeEta +//│ deforest > call f5@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁶) -> //│ deforest > match: a5⁰ @@ -985,6 +1705,63 @@ fun f4(ls4) = if ls4 is h :: t then h + f4(t) Nil then 5 f1(to(4)) + f2(to(5)) + f3(to(6)) + f4(to(7)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta +//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > function to#0 @ to@to -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f3@f3 -> Pure +//│ deforest > call +@result @ f3@f3 -> Pure +//│ deforest > call +@result @ f4@f4 -> Pure +//│ deforest > call +@result @ f4@f4 -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call -@result @ to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call >@result @ to@to -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f1@result @ f1@f1 -> UnsafeEta +//│ deforest > call f1@result @ f1@f1 -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call f2@result @ f2@f2 -> UnsafeEta +//│ deforest > call f2@result @ f2@f2 -> UnsafeEta +//│ deforest > call f3@result @ -> UnsafeEta +//│ deforest > call f3@result @ f3@f3 -> UnsafeEta +//│ deforest > call f3@result @ f3@f3 -> UnsafeEta +//│ deforest > call f4@result @ -> UnsafeEta +//│ deforest > call f4@result @ f4@f4 -> UnsafeEta +//│ deforest > call f4@result @ f4@f4 -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(n⁰, tmp⁸) -> //│ deforest > match: ls4⁰ @@ -1024,6 +1801,51 @@ fun g2(b) = if b then p(3) else p(4) fun f1(p) = if p is AA(a) then a + 1 fun f2(p) = if p is AA(b) then b + 2 f1(wrap(true)) + f2(g2(false)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function g1#0 @ g1@g1 -> UnsafeEta +//│ deforest > function g1#0 @ wrap@wrap.g1@g1 -> UnsafeEta +//│ deforest > function g1#0 @ wrap@wrap.g1@g1 -> UnsafeEta +//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta +//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta +//│ deforest > function p#0 @ g1@g1.p@p -> UnsafeEta +//│ deforest > function p#0 @ g1@g1.p@p -> UnsafeEta +//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta +//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta +//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta +//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta +//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call g1@result @ wrap@wrap -> UnsafeEta +//│ deforest > call g1@result @ wrap@wrap -> UnsafeEta +//│ deforest > call g2@result @ -> UnsafeEta +//│ deforest > call p@result @ g1@g1 -> UnsafeEta +//│ deforest > call p@result @ g1@g1 -> UnsafeEta +//│ deforest > call p@result @ g2@g2 -> UnsafeEta +//│ deforest > call p@result @ g2@g2 -> UnsafeEta +//│ deforest > call p@result @ g2@g2 -> UnsafeEta +//│ deforest > call p@result @ g2@g2 -> UnsafeEta +//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta +//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta +//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta +//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta +//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁷) -> //│ deforest > match: p⁰ @@ -1049,6 +1871,30 @@ fun f1(p) = if p is AA(a) then a + 1 fun f2(p) = if p is AA(b) then b + 2 fun f3(p) = if p is AA(c) then c + 3 f1(one) + f2(one) + f3(two) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f3@f3 -> Pure +//│ deforest > call +@result @ f3@f3 -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call f3@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁸) -> //│ deforest > match: p² @@ -1062,6 +1908,22 @@ fun id(x) = x fun f1(a) = if a is AA(i) then i fun f2(a) = if a is AA(i) then i + 1 f1(id(AA(1))) + f2(id(AA(2))) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function id#0 @ id@id -> Pure +//│ deforest > function id#0 @ id@id -> Pure +//│ deforest > function id#0 @ id@id -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call id@result @ -> Pure +//│ deforest > call id@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> //│ deforest > match: a⁹ @@ -1081,6 +1943,27 @@ fun f1(a1) = if a1 is AA(a) then a + 1 fun f2(a2) = if a2 is AA(a) then a + 2 fun wrap(a) = a f1(wrap(p(2))) + f2(p(1)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function p#0 @ p@p -> UnsafeEta +//│ deforest > function wrap#0 @ wrap@wrap -> Pure +//│ deforest > function wrap#0 @ wrap@wrap -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f1@f1 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call +@result @ f2@f2 -> Pure +//│ deforest > call f1@result @ -> UnsafeEta +//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > call wrap@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁹) -> //│ deforest > match: a2³ diff --git a/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls b/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls index 828e1f84a4..d78fe9b08e 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls @@ -37,6 +37,27 @@ f(3) //│ deforest > tmp_for_f¹ //│ deforest > tmp_for_f⁰ //│ deforest > <<< non-affine syms <<< +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ g@g -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ f@f -> UnsafeEta +//│ deforest > function g#0 @ g@g -> UnsafeEta +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ f@f -> Pure +//│ deforest > call -@result @ g@g -> Pure +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ f@f -> UnsafeEta +//│ deforest > call equals@result @ g@g -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ g@g -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = [ diff --git a/hkmc2/shared/src/test/mlscript/deforest/todos.mls b/hkmc2/shared/src/test/mlscript/deforest/todos.mls index 21f8f05f8a..dc3d2d294e 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/todos.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/todos.mls @@ -7,16 +7,22 @@ object C data class AA(x) data class BB(x) data class CC(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< object Nil data class Cons(h, t) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< object None data class Some(x) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -38,6 +44,37 @@ fun f(a) = if a is AA(AA) then 0 let p = AA(AA(AA(10))) test(p) + f(p) + test(AA(AA(AA(10)))) + test(B) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call -@result @ test@test -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call test@result @ -> Pure +//│ deforest > call test@result @ -> Pure +//│ deforest > call test@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> //│ deforest > match: x⁰ @@ -186,6 +223,13 @@ fun test() = if Global(1) is Global(x) then Local(x + 1) test() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Global⁰(1) -> //│ deforest > match: scrut⁰ @@ -195,10 +239,10 @@ test() //│ deforest > fields: scrut⁰.x² //│ deforest > <<< fusing <<< //│ ╔══[COMPILATION ERROR] No definition found in scope for member 'Local' -//│ ║ l.187: Global(x) then Local(x + 1) +//│ ║ l.224: Global(x) then Local(x + 1) //│ ║ ^^^^^ //│ ╟── which references the symbol introduced here -//│ ║ l.185: data class Local(x) +//│ ║ l.222: data class Local(x) //│ ╙── ^^^^^^^^ //│ ═══[RUNTIME ERROR] ReferenceError: Local is not defined //│ ═══[RUNTIME ERROR] Expected: 'Local(2)', got: 'undefined' @@ -212,6 +256,22 @@ fun test() = let x = A inner(x) + inner(x) test() +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function inner#0 @ inner@inner -> Pure +//│ deforest > function inner#0 @ test@test.inner@inner -> Pure +//│ deforest > function inner#0 @ test@test.inner@inner -> Pure +//│ deforest > function inner#0 @ test@test.inner@inner -> Pure +//│ deforest > function inner#0 @ test@test.inner@inner -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call +@result @ test@test -> Pure +//│ deforest > call inner@result @ test@test -> Pure +//│ deforest > call inner@result @ test@test -> Pure +//│ deforest > call inner@result @ test@test -> Pure +//│ deforest > call inner@result @ test@test -> Pure +//│ deforest > call test@result @ -> Pure +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< //│ = 0 @@ -221,6 +281,14 @@ test() :expect 2 fun f(x) = if x is A then 1 f(A) + f(A) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call +@result @ -> Pure +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> //│ deforest > match: x³ @@ -237,6 +305,13 @@ module Test with fun foo(a) = if a is AA(y) then x + y Test.Test2.foo(AA(2)) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > function foo#0 @ foo@foo -> UnsafeEta +//│ deforest > call +@result @ foo@foo -> Pure +//│ deforest > call +@result @ foo@foo -> Pure +//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> //│ deforest > match: a⁰ diff --git a/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls b/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls index d9bb2a716b..ba5377244b 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls @@ -6,6 +6,8 @@ object Nil data class (::) Cons(h, t) data class Pair(a, b) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -19,6 +21,57 @@ fun unzip(ls_unzip) = if ls_unzip is fun enumFromTo(a, b) = if a < b then a :: enumFromTo(a + 1, b) else Nil fun testUnzipZip(n) = unzip(zip(id(enumFromTo(1, n)), id(enumFromTo(2, n + 3)))) testUnzipZip(3) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > function testUnzipZip#0 @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > function testUnzipZip#0 @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > function unzip#0 @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta +//│ deforest > function unzip#0 @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta +//│ deforest > function unzip#0 @ unzip@unzip -> UnsafeEta +//│ deforest > function zip#0 @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ zip@zip -> UnsafeEta +//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ testUnzipZip@testUnzipZip -> Pure +//│ deforest > call +@result @ testUnzipZip@testUnzipZip -> Pure +//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure +//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta +//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call testUnzipZip@result @ -> UnsafeEta +//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta +//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta +//│ deforest > call unzip@result @ unzip@unzip -> UnsafeEta +//│ deforest > call zip@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call zip@result @ testUnzipZip@testUnzipZip -> UnsafeEta +//│ deforest > call zip@result @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls_unzip⁰ @@ -60,6 +113,46 @@ fun makeZippedList(n) = if n > 0 then Pair(n, n + 1) :: makeZippedList(n - 1) el fun testZipUnzip(n) = if unzip(id(makeZippedList(n))) is Pair(xs, ys) then zip(xs, ys) testZipUnzip(3) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function makeZippedList#0 @ makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > function makeZippedList#0 @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > function makeZippedList#0 @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > function testZipUnzip#0 @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > function testZipUnzip#0 @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > function unzip#0 @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta +//│ deforest > function unzip#0 @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta +//│ deforest > function unzip#0 @ unzip@unzip -> UnsafeEta +//│ deforest > function zip#0 @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ zip@zip -> UnsafeEta +//│ deforest > call +@result @ makeZippedList@makeZippedList -> Pure +//│ deforest > call +@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call +@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call -@result @ makeZippedList@makeZippedList -> Pure +//│ deforest > call -@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call -@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call >@result @ makeZippedList@makeZippedList -> Pure +//│ deforest > call >@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call >@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call id@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call id@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call makeZippedList@result @ makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > call testZipUnzip@result @ -> UnsafeEta +//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta +//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta +//│ deforest > call unzip@result @ unzip@unzip -> UnsafeEta +//│ deforest > call zip@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call zip@result @ testZipUnzip@testZipUnzip -> UnsafeEta +//│ deforest > call zip@result @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: xs_zip⁰ @@ -106,6 +199,73 @@ fun testZipMapBothUnzip(n) = if unzip(id(makeZippedList(n))) is map(x => x * x, ys) ) testZipMapBothUnzip(4) +//│ deforest > >>> effect-analysis results >>> +//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > function makeZippedList#0 @ makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > function makeZippedList#0 @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > function makeZippedList#0 @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > function map#0 @ map@map -> UnsafeEta +//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > function testZipMapBothUnzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > function testZipMapBothUnzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > function unzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta +//│ deforest > function unzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta +//│ deforest > function unzip#0 @ unzip@unzip -> UnsafeEta +//│ deforest > function zip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta +//│ deforest > function zip#0 @ zip@zip -> UnsafeEta +//│ deforest > call *@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > call *@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > call +@result @ makeZippedList@makeZippedList -> Pure +//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure +//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call -@result @ makeZippedList@makeZippedList -> Pure +//│ deforest > call -@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call -@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call >@result @ makeZippedList@makeZippedList -> Pure +//│ deforest > call >@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call >@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure +//│ deforest > call f@result @ map@map -> UnsafeEta +//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure +//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure +//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure +//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure +//│ deforest > call id@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call id@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call makeZippedList@result @ makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta +//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta +//│ deforest > call testZipMapBothUnzip@result @ -> UnsafeEta +//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta +//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta +//│ deforest > call unzip@result @ unzip@unzip -> UnsafeEta +//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta +//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta +//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> //│ deforest > match: ls_map⁰ diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls new file mode 100644 index 0000000000..e39ab2db30 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls @@ -0,0 +1,315 @@ +:lift +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true)), inlining: None) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + +declare fun effect(): Anything +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + +fun leaf_pure(x) = x + 1 +fun node_pure(x) = leaf_pure(x) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_pure#0 @ -> Pure +//│ flow-analysis > function node_pure#0 @ -> Pure +//│ flow-analysis > call +@result @ -> Pure +//│ flow-analysis > call leaf_pure@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + +fun leaf_effectful() = effect() + print() +fun node_effectful() = leaf_effectful() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function node_effectful#0 @ -> UnsafeEta +//│ flow-analysis > call +@result @ -> Pure +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call leaf_effectful@result @ -> UnsafeEta +//│ flow-analysis > call print@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + +fun node_recursive_pure(x) = node_recursive_pure(x) +fun node_recursive_effectful(x) = node_recursive_effectful(leaf_effectful()) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function node_recursive_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function node_recursive_pure#0 @ -> Pure +//│ flow-analysis > call leaf_effectful@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + +open annotations { pure } +@pure +fun leaf() = effect() +fun node() = leaf() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf#0 @ -> Pure +//│ flow-analysis > function node#0 @ -> Pure +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call leaf@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +open annotations { pure } +@pure +declare fun leaf_pure(): Anything +fun node() = leaf_pure() +node() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function node#0 @ -> Pure +//│ flow-analysis > call leaf_pure@result @ -> Pure +//│ flow-analysis > call node@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +class Box(val value) with + fun raise() = effect() +fun node_constructor() = Box(0) +fun node_instantiation() = new Box(0) +fun node_method(box: Box) = box.raise() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function node_constructor#0 @ -> UnsafeEta +//│ flow-analysis > function node_instantiation#0 @ -> UnsafeEta +//│ flow-analysis > function node_method#0 @ -> UnsafeEta +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call raise@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +fun node(f, x) = f(x) +fun leaf_pure(x) = x +fun leaf_effectful(x) = effect() +fun caller_pure() = node(leaf_pure, 0) +fun caller_effectful() = node(leaf_effectful, 0) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function caller_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function caller_pure#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_pure#0 @ -> Pure +//│ flow-analysis > function node#0 @ -> UnsafeEta +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call f@result @ -> UnsafeEta +//│ flow-analysis > call node@result @ -> UnsafeEta +//│ flow-analysis > call node@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +fun leaf(...xs) = 0 +fun node(xs) = leaf(...xs) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf#0 @ -> Pure +//│ flow-analysis > function node#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: false))) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + +fun node(f, x) = f(x) +fun caller_pure() = node((x) => x, 0) +fun caller_effectful() = node((x) => effect(), 0) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function caller_effectful#0 @ caller_effectful@caller_effectful -> UnsafeEta +//│ flow-analysis > function caller_pure#0 @ caller_pure@caller_pure -> Pure +//│ flow-analysis > function lambda#0 @ caller_effectful@caller_effectful.lambda@lambda -> UnsafeEta +//│ flow-analysis > function lambda#0 @ caller_pure@caller_pure.lambda@lambda -> Pure +//│ flow-analysis > function lambda#0 @ lambda@lambda -> Pure +//│ flow-analysis > function lambda#0 @ lambda@lambda -> UnsafeEta +//│ flow-analysis > function node#0 @ caller_effectful@caller_effectful.node@node -> UnsafeEta +//│ flow-analysis > function node#0 @ caller_pure@caller_pure.node@node -> Pure +//│ flow-analysis > function node#0 @ node@node -> UnsafeEta +//│ flow-analysis > call effect@result @ caller_effectful@caller_effectful.lambda@lambda -> UnsafeEta +//│ flow-analysis > call effect@result @ lambda@lambda -> UnsafeEta +//│ flow-analysis > call f@result @ caller_effectful@caller_effectful.node@node -> UnsafeEta +//│ flow-analysis > call f@result @ caller_pure@caller_pure.node@node -> Pure +//│ flow-analysis > call f@result @ node@node -> UnsafeEta +//│ flow-analysis > call node@result @ caller_effectful@caller_effectful -> UnsafeEta +//│ flow-analysis > call node@result @ caller_pure@caller_pure -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +@pure +fun leaf_pure(x) = x +leaf_pure(0) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure +//│ flow-analysis > call leaf_pure@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +declare fun leaf_effectful(): Anything +fun node() = leaf_effectful() +node() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function node#0 @ node@node -> UnsafeEta +//│ flow-analysis > function node#0 @ node@node -> UnsafeEta +//│ flow-analysis > call leaf_effectful@result @ node@node -> UnsafeEta +//│ flow-analysis > call leaf_effectful@result @ node@node -> UnsafeEta +//│ flow-analysis > call node@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// Trusted @pure suppresses spread fallback, including through SCC instantiation. +@pure +fun leaf_pure(...xs) = 0 +fun node(xs) = leaf_pure(...xs) +fun caller(xs) = node(xs) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function caller#0 @ caller@caller -> Pure +//│ flow-analysis > function leaf_pure#0 @ caller@caller.node@node.leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ node@node.leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function node#0 @ caller@caller.node@node -> Pure +//│ flow-analysis > function node#0 @ node@node -> Pure +//│ flow-analysis > call node@result @ caller@caller -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true))) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + +// Explicit latent overrides node to direct and higher-order calls; body calls retain their summaries. +@pure +private fun leaf_pure(x) = effect() +private fun leaf_effectful(x) = effect(); x +private fun node_direct_pure() = leaf_pure(0) +private fun node_direct_effectful() = leaf_effectful(0) +private fun node_pure(f, x) = f(x) +private fun node_effectful(f, x) = f(x) +private fun caller_pure() = node_pure(leaf_pure, 0) +private fun caller_effectful() = node_effectful(leaf_effectful, 0) +node_direct_pure() +node_direct_effectful() +caller_pure() +caller_effectful() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function caller_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function caller_pure#0 @ -> Pure +//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_pure#0 @ -> Pure +//│ flow-analysis > function node_direct_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function node_direct_pure#0 @ -> Pure +//│ flow-analysis > function node_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function node_pure#0 @ -> Pure +//│ flow-analysis > call ,@result @ -> Pure +//│ flow-analysis > call caller_effectful@result @ -> UnsafeEta +//│ flow-analysis > call caller_pure@result @ -> Pure +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call f@result @ -> Pure +//│ flow-analysis > call f@result @ -> UnsafeEta +//│ flow-analysis > call leaf_effectful@result @ -> UnsafeEta +//│ flow-analysis > call leaf_pure@result @ -> Pure +//│ flow-analysis > call node_direct_effectful@result @ -> UnsafeEta +//│ flow-analysis > call node_direct_pure@result @ -> Pure +//│ flow-analysis > call node_effectful@result @ -> UnsafeEta +//│ flow-analysis > call node_pure@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: false))) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + +// Explicit latent overrides node to direct and higher-order calls; body calls retain their summaries. +@pure +private fun leaf_pure(x) = effect() +private fun leaf_effectful(x) = effect(); x +private fun node_direct_pure() = leaf_pure(0) +private fun node_direct_effectful() = leaf_effectful(0) +private fun node_pure(f, x) = f(x) +private fun node_effectful(f, x) = f(x) +private fun caller_pure() = node_pure(leaf_pure, 0) +private fun caller_effectful() = node_effectful(leaf_effectful, 0) +node_direct_pure() +node_direct_effectful() +caller_pure() +caller_effectful() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function caller_effectful#0 @ caller_effectful@caller_effectful -> UnsafeEta +//│ flow-analysis > function caller_effectful#0 @ caller_effectful@caller_effectful -> UnsafeEta +//│ flow-analysis > function caller_pure#0 @ caller_pure@caller_pure -> Pure +//│ flow-analysis > function caller_pure#0 @ caller_pure@caller_pure -> Pure +//│ flow-analysis > function leaf_effectful#0 @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > function leaf_effectful#0 @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > function leaf_effectful#0 @ leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > function leaf_effectful#0 @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > function leaf_effectful#0 @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > function leaf_pure#0 @ caller_pure@caller_pure.leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ caller_pure@caller_pure.leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function node_direct_effectful#0 @ node_direct_effectful@node_direct_effectful -> UnsafeEta +//│ flow-analysis > function node_direct_effectful#0 @ node_direct_effectful@node_direct_effectful -> UnsafeEta +//│ flow-analysis > function node_direct_pure#0 @ node_direct_pure@node_direct_pure -> Pure +//│ flow-analysis > function node_direct_pure#0 @ node_direct_pure@node_direct_pure -> Pure +//│ flow-analysis > function node_effectful#0 @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta +//│ flow-analysis > function node_effectful#0 @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta +//│ flow-analysis > function node_effectful#0 @ node_effectful@node_effectful -> UnsafeEta +//│ flow-analysis > function node_pure#0 @ caller_pure@caller_pure.node_pure@node_pure -> Pure +//│ flow-analysis > function node_pure#0 @ caller_pure@caller_pure.node_pure@node_pure -> Pure +//│ flow-analysis > function node_pure#0 @ node_pure@node_pure -> UnsafeEta +//│ flow-analysis > call ,@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> Pure +//│ flow-analysis > call ,@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> Pure +//│ flow-analysis > call ,@result @ leaf_effectful@leaf_effectful -> Pure +//│ flow-analysis > call ,@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> Pure +//│ flow-analysis > call ,@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> Pure +//│ flow-analysis > call caller_effectful@result @ -> UnsafeEta +//│ flow-analysis > call caller_pure@result @ -> Pure +//│ flow-analysis > call effect@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > call effect@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > call effect@result @ caller_pure@caller_pure.leaf_pure@leaf_pure -> UnsafeEta +//│ flow-analysis > call effect@result @ caller_pure@caller_pure.leaf_pure@leaf_pure -> UnsafeEta +//│ flow-analysis > call effect@result @ leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > call effect@result @ leaf_pure@leaf_pure -> UnsafeEta +//│ flow-analysis > call effect@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > call effect@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta +//│ flow-analysis > call effect@result @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> UnsafeEta +//│ flow-analysis > call effect@result @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> UnsafeEta +//│ flow-analysis > call f@result @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta +//│ flow-analysis > call f@result @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta +//│ flow-analysis > call f@result @ caller_pure@caller_pure.node_pure@node_pure -> Pure +//│ flow-analysis > call f@result @ caller_pure@caller_pure.node_pure@node_pure -> Pure +//│ flow-analysis > call f@result @ node_effectful@node_effectful -> UnsafeEta +//│ flow-analysis > call f@result @ node_pure@node_pure -> UnsafeEta +//│ flow-analysis > call leaf_effectful@result @ node_direct_effectful@node_direct_effectful -> UnsafeEta +//│ flow-analysis > call leaf_effectful@result @ node_direct_effectful@node_direct_effectful -> UnsafeEta +//│ flow-analysis > call leaf_pure@result @ node_direct_pure@node_direct_pure -> Pure +//│ flow-analysis > call leaf_pure@result @ node_direct_pure@node_direct_pure -> Pure +//│ flow-analysis > call node_direct_effectful@result @ -> UnsafeEta +//│ flow-analysis > call node_direct_pure@result @ -> Pure +//│ flow-analysis > call node_effectful@result @ caller_effectful@caller_effectful -> UnsafeEta +//│ flow-analysis > call node_effectful@result @ caller_effectful@caller_effectful -> UnsafeEta +//│ flow-analysis > call node_pure@result @ caller_pure@caller_pure -> Pure +//│ flow-analysis > call node_pure@result @ caller_pure@caller_pure -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true))) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + +@pure +private fun leaf_pure(...xs) = effect() +private fun leaf_effectful(...xs) = effect(); 0 +private fun leaf_inferred_pure(...xs) = 0 +private fun node_pure(xs) = leaf_pure(...xs) +private fun node_effectful(xs) = leaf_effectful(...xs) +private fun node_inferred_pure(xs) = leaf_inferred_pure(...xs) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_inferred_pure#0 @ -> Pure +//│ flow-analysis > function leaf_pure#0 @ -> Pure +//│ flow-analysis > function node_effectful#0 @ -> UnsafeEta +//│ flow-analysis > function node_inferred_pure#0 @ -> UnsafeEta +//│ flow-analysis > function node_pure#0 @ -> Pure +//│ flow-analysis > call ,@result @ -> Pure +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls new file mode 100644 index 0000000000..c7bfef00e6 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls @@ -0,0 +1,74 @@ +// The test harness imports and opens Predef.mls; print's body is outside this program. +:lift +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true)), inlining: None) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + +// Isolate print so another effectful call cannot mask a missing imported-call effect. +fun leaf(x) = print(x) +fun node(x) = leaf(x) +fun qualified(x) = Predef.print(x) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf#0 @ -> UnsafeEta +//│ flow-analysis > function node#0 @ -> UnsafeEta +//│ flow-analysis > function qualified#0 @ -> UnsafeEta +//│ flow-analysis > call leaf@result @ -> UnsafeEta +//│ flow-analysis > call print@result @ -> UnsafeEta +//│ flow-analysis > call print@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// Passing an imported function as a value must also propagate its unknown effect. +private fun invoke(f, x) = f(x) +fun indirect(x) = invoke(print, x) +fun pure_callback(x) = invoke(y => y, x) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function indirect#0 @ -> UnsafeEta +//│ flow-analysis > function invoke#0 @ -> UnsafeEta +//│ flow-analysis > function lambda#0 @ -> Pure +//│ flow-analysis > function pure_callback#0 @ -> UnsafeEta +//│ flow-analysis > call f@result @ -> UnsafeEta +//│ flow-analysis > call invoke@result @ -> UnsafeEta +//│ flow-analysis > call invoke@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: false))) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + +fun leaf(x) = print(x) +fun node(x) = leaf(x) +fun qualified(x) = Predef.print(x) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf#0 @ leaf@leaf -> UnsafeEta +//│ flow-analysis > function leaf#0 @ node@node.leaf@leaf -> UnsafeEta +//│ flow-analysis > function node#0 @ node@node -> UnsafeEta +//│ flow-analysis > function qualified#0 @ qualified@qualified -> UnsafeEta +//│ flow-analysis > call leaf@result @ node@node -> UnsafeEta +//│ flow-analysis > call print@result @ leaf@leaf -> UnsafeEta +//│ flow-analysis > call print@result @ node@node.leaf@leaf -> UnsafeEta +//│ flow-analysis > call print@result @ qualified@qualified -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// Poly mode keeps the pure callback separate from the imported print callback. +private fun invoke(f, x) = f(x) +fun indirect(x) = invoke(print, x) +fun pure_callback(x) = invoke(y => y, x) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function indirect#0 @ indirect@indirect -> UnsafeEta +//│ flow-analysis > function invoke#0 @ indirect@indirect.invoke@invoke -> UnsafeEta +//│ flow-analysis > function invoke#0 @ invoke@invoke -> UnsafeEta +//│ flow-analysis > function invoke#0 @ pure_callback@pure_callback.invoke@invoke -> Pure +//│ flow-analysis > function lambda#0 @ lambda@lambda -> Pure +//│ flow-analysis > function lambda#0 @ pure_callback@pure_callback.lambda@lambda -> Pure +//│ flow-analysis > function pure_callback#0 @ pure_callback@pure_callback -> Pure +//│ flow-analysis > call f@result @ indirect@indirect.invoke@invoke -> UnsafeEta +//│ flow-analysis > call f@result @ invoke@invoke -> UnsafeEta +//│ flow-analysis > call f@result @ pure_callback@pure_callback.invoke@invoke -> Pure +//│ flow-analysis > call invoke@result @ indirect@indirect -> UnsafeEta +//│ flow-analysis > call invoke@result @ pure_callback@pure_callback -> Pure +//│ flow-analysis > <<< effect-analysis results <<< diff --git a/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala b/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala index a7cb944188..d766783162 100644 --- a/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala +++ b/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala @@ -329,6 +329,7 @@ abstract class MLsDiffMaker extends DiffMaker: debugEta = false, debugDpe = false, debugDce = false, + logEffects = false, )) )) processTrees( From c1e2f2e08e9e4933778cb53b54daaccb3a4c8fdb Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 1 Oct 2026 23:33:35 +0800 Subject: [PATCH 2/9] Require lifting before eta expansion If lifting doesn't run, then eta expansion doesn't run. Co-authored-by: Flandia --- .../codegen/FlowAnalysisBasedRewrite.scala | 2 +- .../test/mlscript/dead-param-elim/todos.mls | 1 + .../mlscript/deforest/eta-expansion/basic.mls | 5 ++- .../deforest/eta-expansion/recursive.mls | 1 + .../src/test/mlscript/opt/EtaExpansion.mls | 42 +++++++++++++++---- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala index 1e87748365..1b5488c983 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala @@ -314,7 +314,7 @@ object FlowAnalysisBasedRewrite: ) val etaExpansionSolver = - if eta then new EtaExpansionSolver( + if eta && cfg.liftDefns.isDefined then new EtaExpansionSolver( flowAnalysisRes, mkTl("eta-expansion > ", optCfg.effectiveDebugEta)) else NoEtaExpansion val deadParamElimSolver = diff --git a/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls b/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls index 9d888791c0..8d859f9d13 100644 --- a/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls +++ b/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls @@ -1,4 +1,5 @@ :js +:lift :deforest :flowBasedOpt debugEta debugDpe diff --git a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls index a3604d2557..9aaf98f34b 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls @@ -1,4 +1,5 @@ :js +:lift :deforest :flowBasedOpt debugEta @@ -176,8 +177,8 @@ main(3) //│ deforest > fields: arg$X$0$¹.b⁰ //│ deforest > <<< fusing <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> -//│ eta-expansion > p⁰#0 @ : [1, 3] -//│ eta-expansion > p¹#0 @ : [1, 3] +//│ eta-expansion > p⁰#0 @ : [2, 3] +//│ eta-expansion > p¹#0 @ : [2, 3] //│ eta-expansion > <<< eta-expansion targets shapes <<< //│ = 5 diff --git a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls index 780cb6bedb..1d30f4adcc 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls @@ -1,4 +1,5 @@ :js +:lift :deforest :flowBasedOpt debugEta diff --git a/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls b/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls index 6f6bb3c566..40be162fad 100644 --- a/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls +++ b/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls @@ -1,4 +1,5 @@ :js +:lift :flowBasedOpt debugEta @@ -46,10 +47,15 @@ g(1)(2) fun h(x) = @affine(0) y => x + y h(1)(2) //│ eta-expansion > >>> eta-expansion targets shapes >>> -//│ eta-expansion > h⁰#0 @ : [1, 1] //│ eta-expansion > <<< eta-expansion targets shapes <<< //│ ——————————————| Optimized IR |—————————————————————————————————————————————————————————————————————— -//│ @inline define h⁰ as fun h¹(x)(eta$0$0) { return +⁰(x, eta$0$0) }; return 3 +//│ let lambda$; +//│ @inline @private @affine(0) +//│ define lambda$ as fun lambda$⁰(x)(y) { +//│ return +⁰(x, y) +//│ }; +//│ define h⁰ as fun h¹(x) { return lambda$⁰(x) }; +//│ return 3 //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— //│ = 3 @@ -125,10 +131,10 @@ g(f, 1)(2) + g(h, 3)(4) :w fun h(x) = @affine(1) y => x + y //│ ╔══[WARNING] This annotation has no effect. -//│ ║ l.126: fun h(x) = @affine(1) y => x + y +//│ ║ l.132: fun h(x) = @affine(1) y => x + y //│ ║ ^^^^^^^^^^ //│ ╟── This annotation is not supported on function literal terms. -//│ ║ l.126: fun h(x) = @affine(1) y => x + y +//│ ║ l.132: fun h(x) = @affine(1) y => x + y //│ ╙── ^^^^^^^^^^ //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< @@ -136,7 +142,7 @@ fun h(x) = @affine(1) y => x + y :w @affine(0) val v = 1 //│ ╔══[WARNING] This annotation has no effect. -//│ ║ l.137: @affine(0) val v = 1 +//│ ║ l.143: @affine(0) val v = 1 //│ ╙── ^^^^^^^^^^ //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< @@ -145,10 +151,10 @@ fun h(x) = @affine(1) y => x + y :w fun h(x) = @affine(0) x //│ ╔══[WARNING] This annotation has no effect. -//│ ║ l.146: fun h(x) = @affine(0) x +//│ ║ l.152: fun h(x) = @affine(0) x //│ ║ ^^^^^^^^^^ //│ ╟── This annotation is not supported on reference terms. -//│ ║ l.146: fun h(x) = @affine(0) x +//│ ║ l.152: fun h(x) = @affine(0) x //│ ╙── ^ //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< @@ -277,3 +283,25 @@ app(returnRest2(0)) //│ return app¹(tmp) //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— //│ = [2, 3] + + +// * It doesn't eta-expand if there's no lifting :) +:expect 42 +#config(liftDefns: None) +@affine(0) fun leaf() = 42 +fun node() = leaf +node()() +//│ dead-param-elim > >>> dead-param-elim results >>> +//│ dead-param-elim > <<< dead-param-elim results <<< +//│ = 42 +:expect 42 +#config(liftDefns: Some(LiftDefns)) +@affine(0) fun leaf() = 42 +fun node() = leaf +node()() +//│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > node⁰#0 @ : [0, 0] +//│ eta-expansion > <<< eta-expansion targets shapes <<< +//│ dead-param-elim > >>> dead-param-elim results >>> +//│ dead-param-elim > <<< dead-param-elim results <<< +//│ = 42 From 8357a1c55cc4705885c5047f2d1fb7f9a2fc0aa3 Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 2 Oct 2026 02:39:17 +0800 Subject: [PATCH 3/9] Update purity metadata during eta expansion Carry annotations with rewritten function parameters and bodies so every definition builder consumes the eta rewrite's metadata. Remove stale @pure annotations when adding stages and mark extended calls as potentially effectful. Preserve existing deforestation annotations. Co-authored-by: Flandia --- .../codegen/FlowAnalysisBasedRewrite.scala | 26 ++++++++++++------- .../codegen/PolyInstantiationRewrite.scala | 2 +- .../hkmc2/codegen/deforest/Rewrite.scala | 10 +++---- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala index 1b5488c983..9137f8c8df 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/FlowAnalysisBasedRewrite.scala @@ -113,7 +113,11 @@ class FlowAnalysisBasedRewrite( val body2 = withEliminatedParams(removed): withEtaArgss(etaParams.map(_.args)): applyFunBodyLikeBlock(body) - params2 -> body2 + // The appended stage may be effectful even when the original producer was pure. + val annotations2 = + if etaParams.nonEmpty then fun.annotations.filterNot(_.isInstanceOf[Annot.Pure]) + else fun.annotations + (params2, body2, annotations2) // traversal @@ -138,7 +142,9 @@ class FlowAnalysisBasedRewrite( Return(etaCall(p).withLocOf(res2)) case c @ Call(fun, argss) => Return( - Call(fun, (argss ++ activeEtaArgss).ne_!)(c.metadata, c.toLoc)) + Call(fun, (argss ++ activeEtaArgss).ne_!)(c.metadata.copy( + mayRaiseEffects = true, + annotations = c.metadata.annotations.filterNot(_.isInstanceOf[Annot.Pure])), c.toLoc)) case _ => val tmp = TempSymbol(N, erasedType = N, "eta$res") Scoped( @@ -206,9 +212,9 @@ class FlowAnalysisBasedRewrite( super.applyObjBody(defn) override def applyFunDefn(fun: FunDefn): FunDefn = - val (params2, body2) = rewriteFunDefn(fun) - if (params2 is fun.params) && (body2 is fun.body) then fun - else FunDefn(fun.owner, fun.sym, fun.dSym, params2, body2)(fun.configOverride, fun.annotations) + val (params2, body2, annotations2) = rewriteFunDefn(fun) + if (params2 is fun.params) && (body2 is fun.body) && (annotations2 is fun.annotations) then fun + else FunDefn(fun.owner, fun.sym, fun.dSym, params2, body2)(fun.configOverride, annotations2) override def applyLam(lam: Lambda): Lambda = val lamId: ConcreteFunId = ConcreteId(lam.uid, instId) @@ -236,9 +242,9 @@ class FlowAnalysisBasedRewrite( new Rewriter(Nil): override def applyFunDefn(fun: FunDefn): FunDefn = rewrittenInPlace.get(fun.dSym) match - case S((params, body)) => - if (params is fun.params) && (body is fun.body) then fun - else FunDefn(fun.owner, fun.sym, fun.dSym, params, body)(fun.configOverride, fun.annotations) + case S((params, body, annotations)) => + if (params is fun.params) && (body is fun.body) && (annotations is fun.annotations) then fun + else FunDefn(fun.owner, fun.sym, fun.dSym, params, body)(fun.configOverride, annotations) case N => super.applyFunDefn(fun) def mkPolyFunCopy( @@ -257,7 +263,7 @@ class FlowAnalysisBasedRewrite( case _ => super.applyValue(v)(k) end RefreshSymbol - val (rewrittenParams, rewrittenBody) = rewritten + val (rewrittenParams, rewrittenBody, rewrittenAnnotations) = rewritten val refreshParamMap = MutMap.empty[Symbol, Symbol] def refreshParam(p: Param): Param = val newSym = new VarSymbol(Tree.Ident(p.sym.name), erasedType = p.sym.erasedType) @@ -269,7 +275,7 @@ class FlowAnalysisBasedRewrite( FunDefn( N, bms, tSym, refreshedParams, new RefreshSymbol(refreshParamMap.toMap).apply(rewrittenBody))( - original.configOverride, original.annotations) + original.configOverride, rewrittenAnnotations) end mkPolyFunCopy def otherNewFunDefns: Iterable[FunDefn] = Nil diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/PolyInstantiationRewrite.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/PolyInstantiationRewrite.scala index e2969fb171..b279e275fd 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/PolyInstantiationRewrite.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/PolyInstantiationRewrite.scala @@ -19,7 +19,7 @@ abstract class FlowAnalysisSolverResult: end FlowAnalysisSolverResult -type RewrittenFunDefn = (params: Ls[ParamList], body: Block) +type RewrittenFunDefn = (params: Ls[ParamList], body: Block, annotations: Ls[Annot]) abstract class PolyInstantiationRewrite(val constraintSolver: FlowConstraintSolver): diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/deforest/Rewrite.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/deforest/Rewrite.scala index 9c3d981910..889cef2156 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/deforest/Rewrite.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/deforest/Rewrite.scala @@ -325,7 +325,7 @@ class DeforestRewriter(val solver: DeforestFusionSolver)(using Raise) private class Rewriter(instId: InstantiationId) extends InstantiationRewriter(instId): override def rewriteFunDefn(fun: FunDefn): RewrittenFunDefn = - fun.params -> applyBlock(fun.body) + (fun.params, applyBlock(fun.body), fun.annotations) override def applyResult(r: Result)(k: Result => Block): Block = r match @@ -477,7 +477,7 @@ class DeforestRewriter(val solver: DeforestFusionSolver)(using Raise) tSym: TermSymbol, rewritten: RewrittenFunDefn, ): FunDefn = - val (rewrittenParams, rewrittenBody) = rewritten + val (rewrittenParams, rewrittenBody, rewrittenAnnotations) = rewritten // refresh other local symbols: for funs, we can check existing scoped blocks and // there is no need to add scoped blocks, because function bodies now already are scoped val refreshParamMap = MutMap.empty[VarSymbol, VarSymbol] @@ -492,7 +492,7 @@ class DeforestRewriter(val solver: DeforestFusionSolver)(using Raise) val bodyWithCorrectSymbols = refreshExtractedBody(refreshParamMap.toMap, rewrittenBody) FunDefn( N, bms, tSym, refreshedParams, - bodyWithCorrectSymbols)(N, PrivateModifier :: original.annotations) + bodyWithCorrectSymbols)(N, PrivateModifier :: rewrittenAnnotations) end mkPolyFunCopy @@ -545,10 +545,10 @@ class DeforestRewriter(val solver: DeforestFusionSolver)(using Raise) new Rewriter(Nil): override def applyFunDefn(fun: FunDefn): FunDefn = rewrittenInPlace.get(fun.dSym) match - case Some((params, rewrittenBody)) => + case Some((params, rewrittenBody, annotations)) => // deforest never changes fun params in place assert(params is fun.params) - FunDefn(fun.owner, fun.sym, fun.dSym, params, rewrittenBody)(fun.configOverride, fun.annotations) + FunDefn(fun.owner, fun.sym, fun.dSym, params, rewrittenBody)(fun.configOverride, annotations) case None => super.applyFunDefn(fun) // ====== end: implements the abstract members of `PolyInstantiationRewrite` ====== end DeforestRewriter From c7f413d1db7102ccaff6c553440e5dc9a1540fd0 Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 2 Oct 2026 03:00:28 +0800 Subject: [PATCH 4/9] Preserve affine stage indices during lifting Increment affine annotation indices when lifting adds a capture parameter list, so the annotation continues to describe the original stage. Update the eta-expansion golden output for a captured affine lambda. Co-authored-by: Flandia --- .../src/main/scala/hkmc2/codegen/Lifter.scala | 6 +++++- .../src/test/mlscript/opt/EtaExpansion.mls | 19 +++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/Lifter.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/Lifter.scala index 9bddf3a37d..866b64fd2e 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/Lifter.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/Lifter.scala @@ -1088,6 +1088,10 @@ class Lifter(topLevelBlk: Block)(using State, Raise, Config): val call = Call(fun.sym.asMemberRef(fun.dSym), args ne_:: Nil)(CallMetadata.mlsFunWithEffect, N) val bod = Return(call) + // The new capture list shifts the stages described by affine annotations. + val annotations = fun.annotations.map: + case a @ Annot.Affine(n) => Annot.Affine(n + 1)(a.toLoc) + case a => a FunDefn( N, @@ -1095,7 +1099,7 @@ class Lifter(topLevelBlk: Block)(using State, Raise, Config): auxDsym, newPlists, bod - )(N, if fun.noInline then fun.annotations else Annot.Inline()(N) :: fun.annotations) + )(N, if fun.noInline then annotations else Annot.Inline()(N) :: annotations) private val aux = Lazy[Defn](mkAuxDefn) diff --git a/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls b/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls index 40be162fad..c73ea94268 100644 --- a/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls +++ b/hkmc2/shared/src/test/mlscript/opt/EtaExpansion.mls @@ -47,15 +47,10 @@ g(1)(2) fun h(x) = @affine(0) y => x + y h(1)(2) //│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > h⁰#0 @ : [1, 1] //│ eta-expansion > <<< eta-expansion targets shapes <<< //│ ——————————————| Optimized IR |—————————————————————————————————————————————————————————————————————— -//│ let lambda$; -//│ @inline @private @affine(0) -//│ define lambda$ as fun lambda$⁰(x)(y) { -//│ return +⁰(x, y) -//│ }; -//│ define h⁰ as fun h¹(x) { return lambda$⁰(x) }; -//│ return 3 +//│ @inline define h⁰ as fun h¹(x)(eta$0$0) { return +⁰(x, eta$0$0) }; return 3 //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— //│ = 3 @@ -131,10 +126,10 @@ g(f, 1)(2) + g(h, 3)(4) :w fun h(x) = @affine(1) y => x + y //│ ╔══[WARNING] This annotation has no effect. -//│ ║ l.132: fun h(x) = @affine(1) y => x + y +//│ ║ l.127: fun h(x) = @affine(1) y => x + y //│ ║ ^^^^^^^^^^ //│ ╟── This annotation is not supported on function literal terms. -//│ ║ l.132: fun h(x) = @affine(1) y => x + y +//│ ║ l.127: fun h(x) = @affine(1) y => x + y //│ ╙── ^^^^^^^^^^ //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< @@ -142,7 +137,7 @@ fun h(x) = @affine(1) y => x + y :w @affine(0) val v = 1 //│ ╔══[WARNING] This annotation has no effect. -//│ ║ l.143: @affine(0) val v = 1 +//│ ║ l.138: @affine(0) val v = 1 //│ ╙── ^^^^^^^^^^ //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< @@ -151,10 +146,10 @@ fun h(x) = @affine(1) y => x + y :w fun h(x) = @affine(0) x //│ ╔══[WARNING] This annotation has no effect. -//│ ║ l.152: fun h(x) = @affine(0) x +//│ ║ l.147: fun h(x) = @affine(0) x //│ ║ ^^^^^^^^^^ //│ ╟── This annotation is not supported on reference terms. -//│ ║ l.152: fun h(x) = @affine(0) x +//│ ║ l.147: fun h(x) = @affine(0) x //│ ╙── ^ //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< From b39d5d24b61c0f30fd35636e2942d3928d7c654b Mon Sep 17 00:00:00 2001 From: Flandia Date: Fri, 2 Oct 2026 03:11:04 +0800 Subject: [PATCH 5/9] Eta Expansion Gate --- .../scala/hkmc2/codegen/EtaExpansion.scala | 6 +- .../codegen/flowAnalysis/EffectAnalysis.scala | 6 +- .../deforest/eta-expansion/recursive.mls | 61 +++++----- .../src/test/mlscript/opt/EtaEffects.mls | 109 ++++++++++++++++++ 4 files changed, 149 insertions(+), 33 deletions(-) create mode 100644 hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala index c254431d8d..30ce3ba684 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala @@ -110,7 +110,11 @@ class EtaExpansionSolver(val constraintSolver: FlowConstraintSolver, tl: TraceLo case N => val targets = EtaTargets(pf.params.size, pf.restParam.isDefined, Set.single(pf)) if !processing.contains(pf) then - val res = targets :: funResShape(pf.res) + // It'd be unsound if eta-expansion postpones the evaluation of a + // function if it may have (side) effects. + // TODO: function divergence? + val safe = pf.effect.exists(EffectAnalysis.summarize(_) == EffectSummary.Pure) + val res = targets :: (if safe then funResShape(pf.res) else Nil) cache(pf) = res res else diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala index 55ad9b33ab..7e596fc1e3 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala @@ -21,9 +21,9 @@ object EffectAnalysis: def summarize(effectVar: StratVar): EffectSummary = - if effectVar.lowerBounds.contains(UnsafeEta) - then EffectSummary.UnsafeEta - else EffectSummary.Pure + if effectVar.lowerBounds.forall(_.isInstanceOf[StratVar]) + then EffectSummary.Pure + else EffectSummary.UnsafeEta def apply(solver: FlowConstraintSolver)(using tl: TraceLogger): EffectAnalysisResult = given fState: FlowAnalysis.State = solver.fState diff --git a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls index 1d30f4adcc..a46f8b5f98 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls @@ -155,83 +155,85 @@ len(flatten(id((1 :: 2 :: Nil) :: (3 :: Nil) :: Nil))) //│ deforest > fields: ls¹.t⁰ //│ deforest > <<< fusing <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> -//│ eta-expansion > flatten_append$append⁰#0 @ : [2, 6] -//│ eta-expansion > flatten$flatten⁰#0 @ : [1, 6] //│ eta-expansion > <<< eta-expansion targets shapes <<< //│ ——————————————| Optimized IR |—————————————————————————————————————————————————————————————————————— -//│ let tmp, tmp1, tmp2, tmp3, tmp4, flatten$flatten, flatten_append$append$worker, flatten$flatten$worker; -//│ @inline @private -//│ define flatten$flatten as fun flatten$flatten⁰(xss)(eta$0$1, eta$0$4, eta$0$5) { -//│ return flatten$flatten$worker⁰(xss, eta$0$1, eta$0$4, eta$0$5) -//│ }; +//│ let tmp, tmp1, tmp2, tmp3, tmp4, tmp5, flatten$flatten, flatten_append$append, len$ls_Nil, len$ls_Cons; //│ @private -//│ define flatten$flatten$worker as fun flatten$flatten$worker⁰(xss, eta$0$1, eta$0$4, eta$0$5) { -//│ let arg$Cons$0$, arg$Cons$1$; +//│ define flatten$flatten as fun flatten$flatten⁰(xss) { +//│ let arg$Cons$0$, arg$Cons$1$, tmp6; //│ match xss //│ Nil⁰ => -//│ return 0 +//│ return len$ls_Nil⁰() //│ Cons¹ => -//│ let ys; //│ set arg$Cons$0$ = xss.h⁰; //│ set arg$Cons$1$ = xss.t⁰; -//│ set ys = flatten$flatten⁰(arg$Cons$1$); -//│ return flatten_append$append$worker⁰(arg$Cons$0$, ys, eta$0$1, eta$0$4, eta$0$5) +//│ set tmp6 = flatten$flatten⁰(arg$Cons$1$); +//│ return flatten_append$append⁰(arg$Cons$0$, tmp6) //│ else //│ throw new globalThis⁰.Error⁰("match error") //│ end //│ }; //│ @private -//│ define flatten_append$append$worker as fun flatten_append$append$worker⁰(xs, ys, eta$0$1, eta$0$4, eta$0$5) { -//│ let arg$Cons$1$; +//│ define flatten_append$append as fun flatten_append$append⁰(xs, ys) { +//│ let arg$Cons$1$, tmp6; //│ match xs //│ Nil⁰ => -//│ return ys(eta$0$1, eta$0$4, eta$0$5) +//│ return ys //│ Cons¹ => -//│ let inlinedVal; //│ set arg$Cons$1$ = xs.t⁰; -//│ set inlinedVal = flatten_append$append$worker⁰(arg$Cons$1$, ys, undefined, undefined, undefined); -//│ return +⁰(1, inlinedVal) +//│ set tmp6 = flatten_append$append⁰(arg$Cons$1$, ys); +//│ return len$ls_Cons⁰(tmp6) //│ else //│ throw new globalThis⁰.Error⁰("match error") //│ end //│ }; +//│ @inline @affine(1) @private +//│ define len$ls_Nil as fun len$ls_Nil⁰()(fv_t, fv_arg$Cons$1$, fv_tmp) { +//│ return 0 +//│ }; +//│ @inline @affine(1) @private +//│ define len$ls_Cons as fun len$ls_Cons⁰(Cons_t)(fv_t, fv_arg$Cons$1$, fv_tmp) { +//│ let inlinedVal; +//│ set inlinedVal = Cons_t(undefined, undefined, undefined); +//│ return +⁰(1, inlinedVal) +//│ }; //│ define append⁰ as fun append¹(xs, ys) { -//│ let arg$Cons$0$, arg$Cons$1$, tmp5; +//│ let arg$Cons$0$, arg$Cons$1$, tmp6; //│ match xs //│ Nil⁰ => //│ return ys //│ Cons¹ => //│ set arg$Cons$0$ = xs.h⁰; //│ set arg$Cons$1$ = xs.t⁰; -//│ set tmp5 = append¹(arg$Cons$1$, ys); -//│ return Cons⁰(arg$Cons$0$, tmp5) +//│ set tmp6 = append¹(arg$Cons$1$, ys); +//│ return Cons⁰(arg$Cons$0$, tmp6) //│ else //│ throw new globalThis⁰.Error⁰("match error") //│ end //│ }; //│ define flatten⁰ as fun flatten¹(xss) { -//│ let arg$Cons$0$, arg$Cons$1$, tmp5; +//│ let arg$Cons$0$, arg$Cons$1$, tmp6; //│ match xss //│ Nil⁰ => //│ return Nil⁰ //│ Cons¹ => //│ set arg$Cons$0$ = xss.h⁰; //│ set arg$Cons$1$ = xss.t⁰; -//│ set tmp5 = flatten¹(arg$Cons$1$); -//│ return append¹(arg$Cons$0$, tmp5) +//│ set tmp6 = flatten¹(arg$Cons$1$); +//│ return append¹(arg$Cons$0$, tmp6) //│ else //│ throw new globalThis⁰.Error⁰("match error") //│ end //│ }; //│ define len⁰ as fun len¹(ls) { -//│ let arg$Cons$1$, tmp5; +//│ let arg$Cons$1$, tmp6; //│ match ls //│ Nil⁰ => //│ return 0 //│ Cons¹ => //│ set arg$Cons$1$ = ls.t⁰; -//│ set tmp5 = len¹(arg$Cons$1$); -//│ return +⁰(1, tmp5) +//│ set tmp6 = len¹(arg$Cons$1$); +//│ return +⁰(1, tmp6) //│ else //│ throw new globalThis⁰.Error⁰("match error") //│ end @@ -241,7 +243,8 @@ len(flatten(id((1 :: 2 :: Nil) :: (3 :: Nil) :: Nil))) //│ set tmp2 = Cons⁰(3, Nil⁰); //│ set tmp3 = Cons⁰(tmp2, Nil⁰); //│ set tmp4 = Cons⁰(tmp1, tmp3); -//│ return flatten$flatten$worker⁰(tmp4, undefined, undefined, undefined) +//│ set tmp5 = flatten$flatten⁰(tmp4); +//│ return tmp5(undefined, undefined, undefined) //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— //│ = 3 diff --git a/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls b/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls new file mode 100644 index 0000000000..a5b09b43c6 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls @@ -0,0 +1,109 @@ +:js + +#config(inlining: None, liftDefns: Some(LiftDefns), flowBasedOpt: Some(FlowBasedOpt(logEffects: true, debugEta: true, mono: true))) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< +//│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > <<< eta-expansion targets shapes <<< + + +fun effect() = print() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function effect#0 @ -> UnsafeEta +//│ flow-analysis > call print@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > <<< eta-expansion targets shapes <<< + + +// * Pure doesn't prevent eta-expansion. +:expect 42 +fun pure() = 42 +@affine(0) fun leaf() = 42 +fun node() = + pure() + leaf +node()() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf#0 @ -> Pure +//│ flow-analysis > function node#0 @ -> Pure +//│ flow-analysis > function pure#0 @ -> Pure +//│ flow-analysis > call baseCall@result @ -> Pure +//│ flow-analysis > call node@result @ -> Pure +//│ flow-analysis > call pure@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< +//│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > node⁰#0 @ : [0, 0] +//│ eta-expansion > <<< eta-expansion targets shapes <<< +//│ = 42 + + +// * Unsafe prevents eta-expansion. +:expect 42 +@affine(0) fun leaf() = 42 +fun node() = + effect() + leaf +node()() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf#0 @ -> Pure +//│ flow-analysis > function node#0 @ -> UnsafeEta +//│ flow-analysis > call baseCall@result @ -> Pure +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call node@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > <<< eta-expansion targets shapes <<< +//│ > +//│ = 42 + + +// * Pure works for multi-stage expansion +:expect 42 +fun pure() = 42 +@affine(0) fun leaf_2() = + 42 +@affine(0) fun leaf_1() = + pure() + leaf_2 +fun node() = leaf_1 +node()()() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_1#0 @ -> Pure +//│ flow-analysis > function leaf_2#0 @ -> Pure +//│ flow-analysis > function node#0 @ -> Pure +//│ flow-analysis > function pure#0 @ -> Pure +//│ flow-analysis > call baseCall@result @ -> Pure +//│ flow-analysis > call callPrefix@result @ -> Pure +//│ flow-analysis > call node@result @ -> Pure +//│ flow-analysis > call pure@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< +//│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > node⁰#0 @ : [0, 0, 0] +//│ eta-expansion > leaf_1⁰#0 @ : [0, 0] +//│ eta-expansion > <<< eta-expansion targets shapes <<< +//│ = 42 + +// * Unsafe prevents direct expansion but still expands as far as possible +:expect 42 +@affine(0) fun leaf_2() = + 42 +@affine(0) fun leaf_1() = + effect() + leaf_2 +fun node() = leaf_1 +node()()() +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_1#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_2#0 @ -> Pure +//│ flow-analysis > function node#0 @ -> Pure +//│ flow-analysis > call baseCall@result @ -> UnsafeEta +//│ flow-analysis > call callPrefix@result @ -> Pure +//│ flow-analysis > call effect@result @ -> UnsafeEta +//│ flow-analysis > call node@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< +//│ eta-expansion > >>> eta-expansion targets shapes >>> +//│ eta-expansion > node⁰#0 @ : [0, 0] +//│ eta-expansion > <<< eta-expansion targets shapes <<< +//│ > +//│ = 42 From dce708f154194c1e047124e4d4873ecdaac64326 Mon Sep 17 00:00:00 2001 From: Flandia Date: Sun, 4 Oct 2026 03:05:48 +0800 Subject: [PATCH 6/9] Mutation Analysis --- .../scala/hkmc2/codegen/EtaExpansion.scala | 2 +- .../codegen/flowAnalysis/FlowAnalysis.scala | 63 ++- .../src/main/scala/hkmc2/semantics/Term.scala | 3 +- .../src/test/mlscript/deforest/basic.mls | 12 +- .../src/test/mlscript/deforest/fusibility.mls | 16 +- .../test/mlscript/deforest/nestedMatch.mls | 20 +- .../src/test/mlscript/deforest/recursive.mls | 48 +-- .../src/test/mlscript/deforest/simple.mls | 34 +- .../src/test/mlscript/deforest/todos.mls | 14 +- .../test/mlscript/effect-analysis/Basic.mls | 400 +++++++----------- .../mlscript/effect-analysis/Mutation.mls | 295 +++++++++++++ .../src/test/mlscript/opt/EtaEffects.mls | 8 +- 12 files changed, 568 insertions(+), 347 deletions(-) create mode 100644 hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala index 30ce3ba684..347d9e4fb5 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala @@ -111,7 +111,7 @@ class EtaExpansionSolver(val constraintSolver: FlowConstraintSolver, tl: TraceLo val targets = EtaTargets(pf.params.size, pf.restParam.isDefined, Set.single(pf)) if !processing.contains(pf) then // It'd be unsound if eta-expansion postpones the evaluation of a - // function if it may have (side) effects. + // function if it may have or observe (side) effects. // TODO: function divergence? val safe = pf.effect.exists(EffectAnalysis.summarize(_) == EffectSummary.Pure) val res = targets :: (if safe then funResShape(pf.res) else Nil) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala index 1fd443c9ad..deff466c44 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala @@ -96,6 +96,14 @@ object FlowAnalysis: if tl.doTrace then EffectAnalysis(solver) solver + private[flowAnalysis] def isPureCall(call: Call): Bool = call.fun match + case Value.SimpleRef(b: BuiltinSymbol) => b.isPure + case p => p.targetSymbol.exists: + case s: TermSymbol => s.irFunDefn match + case S(fun) => fun.annotations.exists(_.isInstanceOf[Annot.Pure]) + case N => s.defn.exists(_.annotations.exists(_.isInstanceOf[Annot.Pure])) + case _ => false + def mkTraceLogger( cfg: Config.FlowAnalysisConfig, prefix: Str, @@ -254,7 +262,7 @@ class ProdFun( case object UnknownProd extends MarkerProdStrat -/** The lower bound marker marking an effect variable as effect-raising. */ +/** A coarse effect marker indicating that the variable is unsafe for eta-epansion. */ case object UnsafeEta extends MarkerProdStrat class Ctor( @@ -729,6 +737,10 @@ class FlowConstraintsCollector( private val generatedVars: collection.Map[Symbol, StratVar] = preAnalyzer.res.generatedVars.withDefaultValue(preAnalyzer.res.primitiveStratVar) + + // * This is for effect analysis. The nonlocal variables that are potentially shared. + // * If a function accesses a nonlocal, it is conservatively considered unsafe for eta-expansion. + private val nonlocals = preAnalyzer.res.capturedVars.valuesIterator.flatten.toSet - eState.runtimeSymbol locally { val funsToProdStratScheme = MutMap.empty[TermSymbol, ProdStratScheme] @@ -958,11 +970,16 @@ class FlowConstraintsCollector( def constrainOpaqueResult(r: Result)(using cc: ConstraintsCollector, currentEffect: Opt[StratVar]): Unit = cc.constrain(processResult(r), UnknownCons) + def markUnsafeEta()(using cc: ConstraintsCollector, currentEffect: Opt[StratVar]): Unit = + currentEffect.foreach(e => cc.constrain(UnsafeEta, e)) + def processBlock(b: Block)(using cc: ConstraintsCollector, blkRes: ConsStrat, currentEffect: Opt[StratVar]): Unit = val instId = cc.instId b match case Return(res) => cc.constrain(processResult(res), blkRes) - case Throw(exc) => constrainOpaqueResult(exc) + case Throw(exc) => + markUnsafeEta() + constrainOpaqueResult(exc) case Match(scrut, arms, dflt, rest) => val scrutStrat = processResult(scrut) cc.constrain(scrutStrat, new Dtor(scrut.uid, instId)) @@ -983,17 +1000,21 @@ class FlowConstraintsCollector( val rhsStrat = processResult(rhs) lhs.match case NoSymbol => () - case lhs: (LocalVarSymbol | TermSymbol) => cc.constrain(rhsStrat, generatedVars(lhs)) + case lhs: (LocalVarSymbol | TermSymbol) => + if nonlocals.contains(lhs) then markUnsafeEta() + cc.constrain(rhsStrat, generatedVars(lhs)) processBlock(rest) case TryBlock(sub, finallyDo, rest) => processBlock(sub) processBlock(finallyDo) processBlock(rest) case AssignField(lhs, nme, rhs, rest) => + markUnsafeEta() constrainOpaqueResult(lhs) constrainOpaqueResult(rhs) processBlock(rest) case AssignDynField(lhs, fld, arrayIdx, rhs, rest) => + markUnsafeEta() constrainOpaqueResult(lhs) constrainOpaqueResult(fld) constrainOpaqueResult(rhs) @@ -1004,8 +1025,12 @@ class FlowConstraintsCollector( val rhsStrat = processResult(rhs) cc.constrain(rhsStrat, generatedVars(tsym)) case fun: FunDefn => + // The eta optimizer requires lifting. + // Other definitions are deliberately opaque. + markUnsafeEta() processFunctionDefn(fun) case cls: ClsLikeDefn => + markUnsafeEta() processClsLikeDefn(cls) processBlock(rest) case End(msg) => () @@ -1021,11 +1046,11 @@ class FlowConstraintsCollector( effect def constrainConstructorEffect(result: Result): Unit = val unsafeEta = result match - case call: Call => call.metadata.mayRaiseEffects + case call: Call => !FlowAnalysis.isPureCall(call) case _: Instantiate => true case _ => false // Constructor bodies are not modeled here; instantiation may have effects. - if unsafeEta then currentEffect.foreach(e => cc.constrain(UnsafeEta, e)) + if unsafeEta then markUnsafeEta() def handleCallLike( call: Call, args: List[Arg], @@ -1036,9 +1061,7 @@ class FlowConstraintsCollector( val argsStrat = args.map(a => processResult(a.value)) if args.exists(_.spread.isDefined) then // TODO: preserve callee-effect precision for spread calls without modeling their argument flow. - // Honor trusted call metadata; otherwise mark the caller without a separate call summary. - if call.metadata.mayRaiseEffects then - currentEffect.foreach(e => cc.constrain(UnsafeEta, e)) + markUnsafeEta() cc.constrain(fStrat, UnknownCons) argsStrat.foreach(arg => cc.constrain(arg, UnknownCons)) UnknownProd @@ -1054,6 +1077,7 @@ class FlowConstraintsCollector( callRes r match case sel@TrackableSelect(from, field, owner) => + markUnsafeEta() val fromStrat = processResult(from) val selRes = freshVar("sel_res", cc.forFun) cc.constrain( @@ -1085,7 +1109,7 @@ class FlowConstraintsCollector( case tupSize: Int => registerCtor(new Ctor(c.uid, instId)(tupSize, (0 until tupSize).zip(argsStrat).toList)) case c@CtorProducer(_, args, selectedFrom) => - constrainConstructorEffect(c) + markUnsafeEta() for qual <- selectedFrom do cc.constrain(processResult(qual), UnknownCons) args.foreach(arg => cc.constrain(processResult(arg.value), UnknownCons)) @@ -1113,6 +1137,7 @@ class FlowConstraintsCollector( mkFunProdStrat("lam_res", ps :: Nil, body, lam.uid, Nil) case _: Tuple => lastWords("should be handled in CtorProducer") case Record(_, fields) => + if fields.exists(_.spread) then markUnsafeEta() fields.foreach: case RcdArg(idx, value) => idx.foreach(p => cc.constrain(processResult(p), UnknownCons)) @@ -1121,6 +1146,9 @@ class FlowConstraintsCollector( case p: Path => p match case refSite@FunRef(f, selectedFrom) => + // ? It's a special case for module getters but I'm not sure if + // ? this is good enough. It just conservatively marks it unsafe. + if preAnalyzer.res.funSymToFunDefn.get(f).exists(_.params.isEmpty) then markUnsafeEta() for qual <- selectedFrom do cc.constrain(processResult(qual), UnknownCons) funsToProdStratScheme.get(f) match @@ -1128,19 +1156,26 @@ class FlowConstraintsCollector( fScheme.instantiate(refSite.uid, f) case None => generatedVars(f) case s@Select(qual, name) => + markUnsafeEta() cc.constrain(processResult(qual), UnknownCons) s.symbol.fold(UnknownProd): selSym => generatedVars(selSym) case DynSelect(qual, fld, arrayIdx) => + markUnsafeEta() cc.constrain(processResult(qual), UnknownCons) cc.constrain(processResult(fld), UnknownCons) UnknownProd - case Cast(value, _, _) => + case Cast(value, _, check) => + if check then markUnsafeEta() val valueStrat = processResult(value) cc.constrain(valueStrat, UnknownCons) valueStrat - case Value.MemberRef(_, disamb) => generatedVars(disamb) - case Value.SimpleRef(sym) => generatedVars(sym) + case Value.MemberRef(_, disamb) => + markUnsafeEta() + generatedVars(disamb) + case Value.SimpleRef(sym) => + if nonlocals.contains(sym) then markUnsafeEta() + generatedVars(sym) case Value.This(_) => UnknownProd case Value.Lit(lit) => UnknownProd } @@ -1242,11 +1277,11 @@ class FlowConstraintSolver(val collector: FlowConstraintsCollector): p.effect.foreach(effect => functionEffectVars(p.concreteId) = effect) registerFunctionEffects(p.res) case _ => () - // Trusted call metadata overrides all inferred contributions, not just unknown callees. + // Trusted metadata overrides all inferred contributions, not just unknown callees. // Keep c.effect registered so a trusted-pure call still has a Pure summary. def inferredCallEffect(c: ConsFun): Opt[StratVar] = c.exprId.getResult match - case call: Call if !call.metadata.mayRaiseEffects => N + case call: Call if FlowAnalysis.isPureCall(call) => N case _ => c.effect def handle(constraint: ProdStrat -> ConsStrat): Unit = assert: diff --git a/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala b/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala index 0ea4bd5869..8c4b632c80 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala @@ -36,9 +36,8 @@ enum Annot extends Located: case Generator()(val toLoc: Opt[Loc]) case Async()(val toLoc: Opt[Loc]) case RaiseEffects()(val toLoc: Opt[Loc]) - // Whether the function is guaranteed to not raise effects. // * EffectAnalysis Annotations - // @pure: overriding annotation that the function is pure, i.e. it does not raise effects. + // @pure: overriding annotation that the function is pure. case Pure()(val toLoc: Opt[Loc]) case Config(modify: hkmc2.Config => hkmc2.Config)(val toLoc: Opt[Loc]) // Marks if a function or lambda is one-shot, i.e. called at most once. diff --git a/hkmc2/shared/src/test/mlscript/deforest/basic.mls b/hkmc2/shared/src/test/mlscript/deforest/basic.mls index c4f1b63593..80f23e21c1 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/basic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/basic.mls @@ -194,8 +194,8 @@ fun f(x, y, res) = if x is res + tmp + a f(X(1), Y(2), 3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function _d#0 @ f@f -> Pure -//│ deforest > function _d#0 @ f@f -> Pure +//│ deforest > function _d#0 @ f@f -> UnsafeEta +//│ deforest > function _d#0 @ f@f -> UnsafeEta //│ deforest > function f#0 @ f@f -> UnsafeEta //│ deforest > function f#0 @ f@f -> UnsafeEta //│ deforest > call +@result @ f@f -> Pure @@ -465,13 +465,13 @@ fun f(x) = x.A#x let o = A(1) g(o) + f(o) + o.A#x //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta //│ deforest > function g#0 @ g@g -> UnsafeEta //│ deforest > function g#0 @ g@g -> UnsafeEta //│ deforest > call +@result @ -> Pure //│ deforest > call +@result @ -> Pure -//│ deforest > call f@result @ -> Pure +//│ deforest > call f@result @ -> UnsafeEta //│ deforest > call g@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> @@ -486,7 +486,7 @@ let x = if A(0) is let f() = x f() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ -> Pure +//│ deforest > function f#0 @ -> UnsafeEta //│ deforest > call f@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> diff --git a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls index dd04d88b98..f06ba4fcf5 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls @@ -225,8 +225,8 @@ c(AA(1)) //│ deforest > y_for_c⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function _d#0 @ c@c -> Pure -//│ deforest > function _d#0 @ c@c -> Pure +//│ deforest > function _d#0 @ c@c -> UnsafeEta +//│ deforest > function _d#0 @ c@c -> UnsafeEta //│ deforest > function c#0 @ c@c -> UnsafeEta //│ deforest > function c#0 @ c@c -> UnsafeEta //│ deforest > call c@result @ -> UnsafeEta @@ -247,13 +247,13 @@ let p = AA(AA(AA(10))) in //│ deforest > tmp⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c1#0 @ c1@c1 -> Pure -//│ deforest > function c1#0 @ c1@c1 -> Pure -//│ deforest > function c2#0 @ c2@c2 -> Pure -//│ deforest > function c2#0 @ c2@c2 -> Pure +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta +//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta //│ deforest > call +@result @ -> Pure -//│ deforest > call c1@result @ -> Pure -//│ deforest > call c2@result @ -> Pure +//│ deforest > call c1@result @ -> UnsafeEta +//│ deforest > call c2@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< diff --git a/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls b/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls index 5dde7775d8..7ce5a0106f 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls @@ -704,9 +704,9 @@ test(p(BB(3))) + test(p(CC(3))) + c(p(A)) //│ deforest > function p#0 @ p@p -> UnsafeEta //│ deforest > function p#0 @ p@p -> UnsafeEta //│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta //│ deforest > call +@result @ -> Pure //│ deforest > call +@result @ -> Pure //│ deforest > call +@result @ test@test -> Pure @@ -716,8 +716,8 @@ test(p(BB(3))) + test(p(CC(3))) + c(p(A)) //│ deforest > call p@result @ -> UnsafeEta //│ deforest > call p@result @ -> UnsafeEta //│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call test@result @ -> Pure -//│ deforest > call test@result @ -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x¹⁶) -> @@ -942,8 +942,8 @@ fun cons(ls) = if ls is _ then 0 cons(prod(4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function cons#0 @ cons@cons -> Pure -//│ deforest > function cons#0 @ cons@cons -> Pure +//│ deforest > function cons#0 @ cons@cons -> UnsafeEta +//│ deforest > function cons#0 @ cons@cons -> UnsafeEta //│ deforest > function prod#0 @ prod@prod -> UnsafeEta //│ deforest > function prod#0 @ prod@prod -> UnsafeEta //│ deforest > call +@result @ cons@cons -> Pure @@ -952,9 +952,9 @@ cons(prod(4)) //│ deforest > call +@result @ cons@cons -> Pure //│ deforest > call -@result @ prod@prod -> Pure //│ deforest > call -@result @ prod@prod -> Pure -//│ deforest > call cons@result @ -> Pure -//│ deforest > call cons@result @ cons@cons -> Pure -//│ deforest > call cons@result @ cons@cons -> Pure +//│ deforest > call cons@result @ -> UnsafeEta +//│ deforest > call cons@result @ cons@cons -> UnsafeEta +//│ deforest > call cons@result @ cons@cons -> UnsafeEta //│ deforest > call prod@result @ -> UnsafeEta //│ deforest > call prod@result @ prod@prod -> UnsafeEta //│ deforest > call prod@result @ prod@prod -> UnsafeEta diff --git a/hkmc2/shared/src/test/mlscript/deforest/recursive.mls b/hkmc2/shared/src/test/mlscript/deforest/recursive.mls index 043b8eff46..96a69bc9ca 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/recursive.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/recursive.mls @@ -2212,30 +2212,30 @@ fun f() = [() => h(B), () => h(B), () => h(B), () => h(B), h(B)] f //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function h#0 @ f@f -> UnsafeEta +//│ deforest > function h#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > function lambda#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/simple.mls b/hkmc2/shared/src/test/mlscript/deforest/simple.mls index 5d0750cdc5..432be98008 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/simple.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/simple.mls @@ -576,11 +576,11 @@ fun c(x, m) = if x is else m c(BB(3), 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> Pure -//│ deforest > function c#0 @ c@c -> Pure +//│ deforest > function c#0 @ c@c -> UnsafeEta +//│ deforest > function c#0 @ c@c -> UnsafeEta //│ deforest > call +@result @ c@c -> Pure //│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> Pure +//│ deforest > call c@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> @@ -626,9 +626,9 @@ f(AA(AA(0))) fun f(x) = x.AA#aa.AA#aa f(AA(AA(3))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > call f@result @ -> Pure +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > function f#0 @ f@f -> UnsafeEta +//│ deforest > call f@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp³) -> @@ -772,12 +772,12 @@ fun test(a) = if a is else 2 test(B) + test(C) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta //│ deforest > call +@result @ -> Pure -//│ deforest > call test@result @ -> Pure -//│ deforest > call test@result @ -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > C⁰ -> @@ -1532,17 +1532,17 @@ f([]) //│ deforest > >>> effect-analysis results >>> //│ deforest > function f#0 @ f@f -> UnsafeEta //│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function h#0 @ f@f -> Pure +//│ deforest > function h#0 @ f@f -> UnsafeEta +//│ deforest > function h#0 @ f@f -> UnsafeEta //│ deforest > call -@result @ f@f -> Pure //│ deforest > call -@result @ f@f -> Pure //│ deforest > call >@result @ f@f -> Pure //│ deforest > call >@result @ f@f -> Pure //│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > call h@result @ f@f -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [] -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/todos.mls b/hkmc2/shared/src/test/mlscript/deforest/todos.mls index dc3d2d294e..b85fe4b1a1 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/todos.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/todos.mls @@ -47,10 +47,10 @@ test(p) + f(p) + test(AA(AA(AA(10)))) + test(B) //│ deforest > >>> effect-analysis results >>> //│ deforest > function f#0 @ f@f -> UnsafeEta //│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta +//│ deforest > function test#0 @ test@test -> UnsafeEta //│ deforest > call +@result @ -> Pure //│ deforest > call +@result @ -> Pure //│ deforest > call +@result @ -> Pure @@ -71,9 +71,9 @@ test(p) + f(p) + test(AA(AA(AA(10)))) + test(B) //│ deforest > call -@result @ test@test -> Pure //│ deforest > call -@result @ test@test -> Pure //│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call test@result @ -> Pure -//│ deforest > call test@result @ -> Pure -//│ deforest > call test@result @ -> Pure +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > call test@result @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls index e39ab2db30..64dda93872 100644 --- a/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls @@ -1,14 +1,18 @@ -:lift -#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true)), inlining: None) +:js + +#config(inlining: None, liftDefns: Some(LiftDefns), flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true))) //│ flow-analysis > >>> effect-analysis results >>> //│ flow-analysis > <<< effect-analysis results <<< - -declare fun effect(): Anything +open annotations { pure } +declare fun unsafe(): Anything //│ flow-analysis > >>> effect-analysis results >>> //│ flow-analysis > <<< effect-analysis results <<< -fun leaf_pure(x) = x + 1 + + +// * Pure remains pure through calls +fun leaf_pure(x) = x + 42 fun node_pure(x) = leaf_pure(x) //│ flow-analysis > >>> effect-analysis results >>> //│ flow-analysis > function leaf_pure#0 @ -> Pure @@ -17,299 +21,187 @@ fun node_pure(x) = leaf_pure(x) //│ flow-analysis > call leaf_pure@result @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< -fun leaf_effectful() = effect() + print() -fun node_effectful() = leaf_effectful() -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function node_effectful#0 @ -> UnsafeEta -//│ flow-analysis > call +@result @ -> Pure -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call leaf_effectful@result @ -> UnsafeEta -//│ flow-analysis > call print@result @ -> UnsafeEta -//│ flow-analysis > <<< effect-analysis results <<< - -fun node_recursive_pure(x) = node_recursive_pure(x) -fun node_recursive_effectful(x) = node_recursive_effectful(leaf_effectful()) -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function node_recursive_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function node_recursive_pure#0 @ -> Pure -//│ flow-analysis > call leaf_effectful@result @ -> UnsafeEta -//│ flow-analysis > <<< effect-analysis results <<< - -open annotations { pure } -@pure -fun leaf() = effect() -fun node() = leaf() -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf#0 @ -> Pure -//│ flow-analysis > function node#0 @ -> Pure -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call leaf@result @ -> Pure -//│ flow-analysis > <<< effect-analysis results <<< - - -open annotations { pure } -@pure -declare fun leaf_pure(): Anything -fun node() = leaf_pure() -node() -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function node#0 @ -> Pure -//│ flow-analysis > call leaf_pure@result @ -> Pure -//│ flow-analysis > call node@result @ -> Pure -//│ flow-analysis > <<< effect-analysis results <<< - -class Box(val value) with - fun raise() = effect() -fun node_constructor() = Box(0) -fun node_instantiation() = new Box(0) -fun node_method(box: Box) = box.raise() +// * Unsafe propagates through calls; unknown calls are unsafe. +fun leaf_unsafe(x) = unsafe() +fun node_unsafe(x) = leaf_unsafe(x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function node_constructor#0 @ -> UnsafeEta -//│ flow-analysis > function node_instantiation#0 @ -> UnsafeEta -//│ flow-analysis > function node_method#0 @ -> UnsafeEta -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call raise@result @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe#0 @ -> UnsafeEta +//│ flow-analysis > function node_unsafe#0 @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe@result @ -> UnsafeEta +//│ flow-analysis > call unsafe@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< -fun node(f, x) = f(x) -fun leaf_pure(x) = x -fun leaf_effectful(x) = effect() -fun caller_pure() = node(leaf_pure, 0) -fun caller_effectful() = node(leaf_effectful, 0) +// * Unsafe propagates through calls; unknown calls are unsafe. +fun leaf_unsafe(x) = print(42) +fun node_unsafe(x) = leaf_unsafe(x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function caller_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function caller_pure#0 @ -> UnsafeEta -//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function leaf_pure#0 @ -> Pure -//│ flow-analysis > function node#0 @ -> UnsafeEta -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call f@result @ -> UnsafeEta -//│ flow-analysis > call node@result @ -> UnsafeEta -//│ flow-analysis > call node@result @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe#0 @ -> UnsafeEta +//│ flow-analysis > function node_unsafe#0 @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe@result @ -> UnsafeEta +//│ flow-analysis > call print@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< -fun leaf(...xs) = 0 -fun node(xs) = leaf(...xs) -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf#0 @ -> Pure +// * Propagation through higher-order calls (monomorphic). +fun answer() = 42 +fun leaf_pure_public(x) = x() +private fun leaf_pure_private(x) = x() +fun leaf_unsafe_public(x) = x() +private fun leaf_unsafe_private(x) = x() +fun node() = + leaf_pure_public(answer) + leaf_pure_private(answer) + leaf_unsafe_public(unsafe) + leaf_unsafe_private(unsafe) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function answer#0 @ -> Pure +//│ flow-analysis > function leaf_pure_private#0 @ -> Pure +//│ flow-analysis > function leaf_pure_public#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_private#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_public#0 @ -> UnsafeEta //│ flow-analysis > function node#0 @ -> UnsafeEta +//│ flow-analysis > call leaf_pure_private@result @ -> Pure +//│ flow-analysis > call leaf_pure_public@result @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe_private@result @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe_public@result @ -> UnsafeEta +//│ flow-analysis > call x@result @ -> Pure +//│ flow-analysis > call x@result @ -> UnsafeEta +//│ flow-analysis > call x@result @ -> UnsafeEta +//│ flow-analysis > call x@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< - -#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: false))) +// * Recursive calls propagate pure and unsafe. +fun node_recursive_pure() = node_recursive_pure() +fun node_recursive_unsafe() = unsafe(); node_recursive_unsafe() //│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function node_recursive_pure#0 @ -> Pure +//│ flow-analysis > function node_recursive_unsafe#0 @ -> UnsafeEta +//│ flow-analysis > call ,@result @ -> Pure +//│ flow-analysis > call node_recursive_unsafe@result @ -> UnsafeEta +//│ flow-analysis > call unsafe@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< -fun node(f, x) = f(x) -fun caller_pure() = node((x) => x, 0) -fun caller_effectful() = node((x) => effect(), 0) +// * @pure is trusted to be pure. +@pure fun leaf_pure() = unsafe() +fun node_pure() = leaf_pure() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function caller_effectful#0 @ caller_effectful@caller_effectful -> UnsafeEta -//│ flow-analysis > function caller_pure#0 @ caller_pure@caller_pure -> Pure -//│ flow-analysis > function lambda#0 @ caller_effectful@caller_effectful.lambda@lambda -> UnsafeEta -//│ flow-analysis > function lambda#0 @ caller_pure@caller_pure.lambda@lambda -> Pure -//│ flow-analysis > function lambda#0 @ lambda@lambda -> Pure -//│ flow-analysis > function lambda#0 @ lambda@lambda -> UnsafeEta -//│ flow-analysis > function node#0 @ caller_effectful@caller_effectful.node@node -> UnsafeEta -//│ flow-analysis > function node#0 @ caller_pure@caller_pure.node@node -> Pure -//│ flow-analysis > function node#0 @ node@node -> UnsafeEta -//│ flow-analysis > call effect@result @ caller_effectful@caller_effectful.lambda@lambda -> UnsafeEta -//│ flow-analysis > call effect@result @ lambda@lambda -> UnsafeEta -//│ flow-analysis > call f@result @ caller_effectful@caller_effectful.node@node -> UnsafeEta -//│ flow-analysis > call f@result @ caller_pure@caller_pure.node@node -> Pure -//│ flow-analysis > call f@result @ node@node -> UnsafeEta -//│ flow-analysis > call node@result @ caller_effectful@caller_effectful -> UnsafeEta -//│ flow-analysis > call node@result @ caller_pure@caller_pure -> Pure +//│ flow-analysis > function leaf_pure#0 @ -> Pure +//│ flow-analysis > function node_pure#0 @ -> Pure +//│ flow-analysis > call leaf_pure@result @ -> Pure +//│ flow-analysis > call unsafe@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< -@pure -fun leaf_pure(x) = x -leaf_pure(0) +// * @pure is trusted to be pure. +@pure declare fun leaf_pure(): Anything +fun node_pure() = leaf_pure() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure +//│ flow-analysis > function node_pure#0 @ -> Pure //│ flow-analysis > call leaf_pure@result @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< -declare fun leaf_effectful(): Anything -fun node() = leaf_effectful() -node() +// * Methods & Constructors. +// * Methods are unsafe because it's unknwon in compilation time. +// * Constructors are unsafe because it's a limitation of the alaysis implementation. +// TODO: Refine the analysis? +class Box() with + fun pure() = 42 + fun unsafe() = unsafe() +fun box_constructor() = Box() +fun box_instantiation() = new Box() +fun box_pure(box: Box) = box.pure() +fun box_unsafe(box: Box) = box.unsafe() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function node#0 @ node@node -> UnsafeEta -//│ flow-analysis > function node#0 @ node@node -> UnsafeEta -//│ flow-analysis > call leaf_effectful@result @ node@node -> UnsafeEta -//│ flow-analysis > call leaf_effectful@result @ node@node -> UnsafeEta -//│ flow-analysis > call node@result @ -> UnsafeEta +//│ flow-analysis > function box_constructor#0 @ -> UnsafeEta +//│ flow-analysis > function box_instantiation#0 @ -> UnsafeEta +//│ flow-analysis > function box_pure#0 @ -> UnsafeEta +//│ flow-analysis > function box_unsafe#0 @ -> UnsafeEta +//│ flow-analysis > call pure@result @ -> UnsafeEta +//│ flow-analysis > call unsafe@result @ -> UnsafeEta +//│ flow-analysis > call unsafe@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< -// Trusted @pure suppresses spread fallback, including through SCC instantiation. +// * Spreading is conservatively unsafe. @pure -fun leaf_pure(...xs) = 0 -fun node(xs) = leaf_pure(...xs) -fun caller(xs) = node(xs) -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function caller#0 @ caller@caller -> Pure -//│ flow-analysis > function leaf_pure#0 @ caller@caller.node@node.leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function leaf_pure#0 @ node@node.leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function node#0 @ caller@caller.node@node -> Pure -//│ flow-analysis > function node#0 @ node@node -> Pure -//│ flow-analysis > call node@result @ caller@caller -> Pure -//│ flow-analysis > <<< effect-analysis results <<< - - -#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true))) +fun leaf_pure_1(...xs) = unsafe() +fun leaf_pure_2(...xs) = 42 +fun node_pure_1(xs) = leaf_pure_1(...xs) +fun node_pure_2(xs) = leaf_pure_2(...xs) +fun node_pure_3(xs) = leaf_pure_1(1, 2, 3) +fun node_pure_4(xs) = leaf_pure_2(1, 2, 3) //│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_pure_1#0 @ -> Pure +//│ flow-analysis > function leaf_pure_2#0 @ -> Pure +//│ flow-analysis > function node_pure_1#0 @ -> UnsafeEta +//│ flow-analysis > function node_pure_2#0 @ -> UnsafeEta +//│ flow-analysis > function node_pure_3#0 @ -> Pure +//│ flow-analysis > function node_pure_4#0 @ -> Pure +//│ flow-analysis > call leaf_pure_1@result @ -> Pure +//│ flow-analysis > call leaf_pure_2@result @ -> Pure +//│ flow-analysis > call unsafe@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< -// Explicit latent overrides node to direct and higher-order calls; body calls retain their summaries. -@pure -private fun leaf_pure(x) = effect() -private fun leaf_effectful(x) = effect(); x -private fun node_direct_pure() = leaf_pure(0) -private fun node_direct_effectful() = leaf_effectful(0) -private fun node_pure(f, x) = f(x) -private fun node_effectful(f, x) = f(x) -private fun caller_pure() = node_pure(leaf_pure, 0) -private fun caller_effectful() = node_effectful(leaf_effectful, 0) -node_direct_pure() -node_direct_effectful() -caller_pure() -caller_effectful() +// ? See below... +fun pure() = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function caller_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function caller_pure#0 @ -> Pure -//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function leaf_pure#0 @ -> Pure -//│ flow-analysis > function node_direct_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function node_direct_pure#0 @ -> Pure -//│ flow-analysis > function node_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function node_pure#0 @ -> Pure -//│ flow-analysis > call ,@result @ -> Pure -//│ flow-analysis > call caller_effectful@result @ -> UnsafeEta -//│ flow-analysis > call caller_pure@result @ -> Pure -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call f@result @ -> Pure -//│ flow-analysis > call f@result @ -> UnsafeEta -//│ flow-analysis > call leaf_effectful@result @ -> UnsafeEta -//│ flow-analysis > call leaf_pure@result @ -> Pure -//│ flow-analysis > call node_direct_effectful@result @ -> UnsafeEta -//│ flow-analysis > call node_direct_pure@result @ -> Pure -//│ flow-analysis > call node_effectful@result @ -> UnsafeEta -//│ flow-analysis > call node_pure@result @ -> Pure +//│ flow-analysis > function pure#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< - -#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: false))) +// ? It seems that flow analysis runs per-block separately... +// ? Is that intended? pure() is seen as a unknwon function in leaf_pure. +fun leaf_pure(x) = pure() //│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function leaf_pure#0 @ -> UnsafeEta +//│ flow-analysis > call pure@result @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< -// Explicit latent overrides node to direct and higher-order calls; body calls retain their summaries. -@pure -private fun leaf_pure(x) = effect() -private fun leaf_effectful(x) = effect(); x -private fun node_direct_pure() = leaf_pure(0) -private fun node_direct_effectful() = leaf_effectful(0) -private fun node_pure(f, x) = f(x) -private fun node_effectful(f, x) = f(x) -private fun caller_pure() = node_pure(leaf_pure, 0) -private fun caller_effectful() = node_effectful(leaf_effectful, 0) -node_direct_pure() -node_direct_effectful() -caller_pure() -caller_effectful() -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function caller_effectful#0 @ caller_effectful@caller_effectful -> UnsafeEta -//│ flow-analysis > function caller_effectful#0 @ caller_effectful@caller_effectful -> UnsafeEta -//│ flow-analysis > function caller_pure#0 @ caller_pure@caller_pure -> Pure -//│ flow-analysis > function caller_pure#0 @ caller_pure@caller_pure -> Pure -//│ flow-analysis > function leaf_effectful#0 @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > function leaf_effectful#0 @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > function leaf_effectful#0 @ leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > function leaf_effectful#0 @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > function leaf_effectful#0 @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > function leaf_pure#0 @ caller_pure@caller_pure.leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function leaf_pure#0 @ caller_pure@caller_pure.leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function leaf_pure#0 @ leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function leaf_pure#0 @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function leaf_pure#0 @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> Pure -//│ flow-analysis > function node_direct_effectful#0 @ node_direct_effectful@node_direct_effectful -> UnsafeEta -//│ flow-analysis > function node_direct_effectful#0 @ node_direct_effectful@node_direct_effectful -> UnsafeEta -//│ flow-analysis > function node_direct_pure#0 @ node_direct_pure@node_direct_pure -> Pure -//│ flow-analysis > function node_direct_pure#0 @ node_direct_pure@node_direct_pure -> Pure -//│ flow-analysis > function node_effectful#0 @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta -//│ flow-analysis > function node_effectful#0 @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta -//│ flow-analysis > function node_effectful#0 @ node_effectful@node_effectful -> UnsafeEta -//│ flow-analysis > function node_pure#0 @ caller_pure@caller_pure.node_pure@node_pure -> Pure -//│ flow-analysis > function node_pure#0 @ caller_pure@caller_pure.node_pure@node_pure -> Pure -//│ flow-analysis > function node_pure#0 @ node_pure@node_pure -> UnsafeEta -//│ flow-analysis > call ,@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> Pure -//│ flow-analysis > call ,@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> Pure -//│ flow-analysis > call ,@result @ leaf_effectful@leaf_effectful -> Pure -//│ flow-analysis > call ,@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> Pure -//│ flow-analysis > call ,@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> Pure -//│ flow-analysis > call caller_effectful@result @ -> UnsafeEta -//│ flow-analysis > call caller_pure@result @ -> Pure -//│ flow-analysis > call effect@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > call effect@result @ caller_effectful@caller_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > call effect@result @ caller_pure@caller_pure.leaf_pure@leaf_pure -> UnsafeEta -//│ flow-analysis > call effect@result @ caller_pure@caller_pure.leaf_pure@leaf_pure -> UnsafeEta -//│ flow-analysis > call effect@result @ leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > call effect@result @ leaf_pure@leaf_pure -> UnsafeEta -//│ flow-analysis > call effect@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > call effect@result @ node_direct_effectful@node_direct_effectful.leaf_effectful@leaf_effectful -> UnsafeEta -//│ flow-analysis > call effect@result @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> UnsafeEta -//│ flow-analysis > call effect@result @ node_direct_pure@node_direct_pure.leaf_pure@leaf_pure -> UnsafeEta -//│ flow-analysis > call f@result @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta -//│ flow-analysis > call f@result @ caller_effectful@caller_effectful.node_effectful@node_effectful -> UnsafeEta -//│ flow-analysis > call f@result @ caller_pure@caller_pure.node_pure@node_pure -> Pure -//│ flow-analysis > call f@result @ caller_pure@caller_pure.node_pure@node_pure -> Pure -//│ flow-analysis > call f@result @ node_effectful@node_effectful -> UnsafeEta -//│ flow-analysis > call f@result @ node_pure@node_pure -> UnsafeEta -//│ flow-analysis > call leaf_effectful@result @ node_direct_effectful@node_direct_effectful -> UnsafeEta -//│ flow-analysis > call leaf_effectful@result @ node_direct_effectful@node_direct_effectful -> UnsafeEta -//│ flow-analysis > call leaf_pure@result @ node_direct_pure@node_direct_pure -> Pure -//│ flow-analysis > call leaf_pure@result @ node_direct_pure@node_direct_pure -> Pure -//│ flow-analysis > call node_direct_effectful@result @ -> UnsafeEta -//│ flow-analysis > call node_direct_pure@result @ -> Pure -//│ flow-analysis > call node_effectful@result @ caller_effectful@caller_effectful -> UnsafeEta -//│ flow-analysis > call node_effectful@result @ caller_effectful@caller_effectful -> UnsafeEta -//│ flow-analysis > call node_pure@result @ caller_pure@caller_pure -> Pure -//│ flow-analysis > call node_pure@result @ caller_pure@caller_pure -> Pure -//│ flow-analysis > <<< effect-analysis results <<< - -#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true))) +#config(flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: false))) //│ flow-analysis > >>> effect-analysis results >>> //│ flow-analysis > <<< effect-analysis results <<< -@pure -private fun leaf_pure(...xs) = effect() -private fun leaf_effectful(...xs) = effect(); 0 -private fun leaf_inferred_pure(...xs) = 0 -private fun node_pure(xs) = leaf_pure(...xs) -private fun node_effectful(xs) = leaf_effectful(...xs) -private fun node_inferred_pure(xs) = leaf_inferred_pure(...xs) -//│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function leaf_inferred_pure#0 @ -> Pure -//│ flow-analysis > function leaf_pure#0 @ -> Pure -//│ flow-analysis > function node_effectful#0 @ -> UnsafeEta -//│ flow-analysis > function node_inferred_pure#0 @ -> UnsafeEta -//│ flow-analysis > function node_pure#0 @ -> Pure -//│ flow-analysis > call ,@result @ -> Pure -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call effect@result @ -> UnsafeEta +// * Propagation through higher-order calls (polymorphic). +fun answer() = 42 +fun leaf_pure_public(x) = x() +private fun leaf_pure_private(x) = x() +fun leaf_unsafe_public(x) = x() +private fun leaf_unsafe_private(x) = x() +fun node() = + leaf_pure_public(answer) + leaf_pure_private(answer) + leaf_unsafe_public(unsafe) + leaf_unsafe_private(unsafe) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function answer#0 @ answer@answer -> Pure +//│ flow-analysis > function answer#0 @ node@node.answer@answer -> Pure +//│ flow-analysis > function answer#0 @ node@node.answer@answer -> Pure +//│ flow-analysis > function leaf_pure_private#0 @ leaf_pure_private@leaf_pure_private -> UnsafeEta +//│ flow-analysis > function leaf_pure_private#0 @ node@node.leaf_pure_private@leaf_pure_private -> Pure +//│ flow-analysis > function leaf_pure_public#0 @ leaf_pure_public@leaf_pure_public -> UnsafeEta +//│ flow-analysis > function leaf_pure_public#0 @ node@node.leaf_pure_public@leaf_pure_public -> Pure +//│ flow-analysis > function leaf_unsafe_private#0 @ leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_private#0 @ node@node.leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_public#0 @ leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_public#0 @ node@node.leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta +//│ flow-analysis > function node#0 @ node@node -> UnsafeEta +//│ flow-analysis > call leaf_pure_private@result @ node@node -> Pure +//│ flow-analysis > call leaf_pure_public@result @ node@node -> Pure +//│ flow-analysis > call leaf_unsafe_private@result @ node@node -> UnsafeEta +//│ flow-analysis > call leaf_unsafe_public@result @ node@node -> UnsafeEta +//│ flow-analysis > call x@result @ leaf_pure_private@leaf_pure_private -> UnsafeEta +//│ flow-analysis > call x@result @ leaf_pure_public@leaf_pure_public -> UnsafeEta +//│ flow-analysis > call x@result @ leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta +//│ flow-analysis > call x@result @ leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta +//│ flow-analysis > call x@result @ node@node.leaf_pure_private@leaf_pure_private -> Pure +//│ flow-analysis > call x@result @ node@node.leaf_pure_public@leaf_pure_public -> Pure +//│ flow-analysis > call x@result @ node@node.leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta +//│ flow-analysis > call x@result @ node@node.leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls new file mode 100644 index 0000000000..2613e19684 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls @@ -0,0 +1,295 @@ +:js + +#config(inlining: None, liftDefns: Some(LiftDefn), flowBasedOpt: Some(FlowBasedOpt(logEffects: true, mono: true))) +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< + + + +// * Mutating a state is an effect. +let state = 0 +fun mutate() = + set state = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = 0 + + +// * Mutating a local (unescaped) variable is pure. +fun mutate_local() = + let local = 0 + set local = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_local#0 @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Reassigning a local copy does not mutate the input binding. +fun mutate_alias(value) = + let local = value + set local = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_alias#0 @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Mutating a local (escaped, captured) variable is an effect. +fun mutate_captured() = + let local = 0 + () => + set local = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function lambda#0 @ -> UnsafeEta +//│ flow-analysis > function lambda$#0 @ -> Pure +//│ flow-analysis > function lambda$#1 @ -> UnsafeEta +//│ flow-analysis > function mutate_captured#0 @ -> UnsafeEta +//│ flow-analysis > call lambda$@result @ -> Pure +//│ flow-analysis > call lambda@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Mutating a state field is an effect. +let state = mut { value: 0 } +fun mutate_field() = + set state.value = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_field#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = {value: 0} + +// * Mutating a state element is an effect. +let state = mut [0] +fun mutate_element() = + set state.[0] = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_element#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = [0] + + +// * Mutating a local field/element is pure. +// TODO: this shouldn't be an effect because the local is unescaped +// to be refined by a "capture-tracking-based local mutation escape analysis" +fun mutate_local_field() = + let local = mut { value: 0 } + set local.value = 42 +fun mutate_local_element() = + let local = mut [0] + set local.[0] = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_local_element#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_local_field#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Mutating an aliased field/element is an effect. +fun mutate_alias_field(obj) = + let local = obj + set local.value = 42 +fun mutate_alias_element(xs) = + let local = xs + set local.[0] = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_alias_element#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_alias_field#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Observing a state is an effect. +// TODO: this shouldn't be an effect because state is immutable +// to be refined by distinguishing between init and assign +let state = 0 +fun observe() = + state +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = 0 + + +// * Observing a local (unescaped) variable is pure. +fun observe_local() = + let local = 0 + local +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe_local#0 @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Observing a local copy of a parameter is pure. +fun observe_alias(value) = + let local = value + local +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe_alias#0 @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Observing a local (escaped, captured) variable is pure. +fun observe_captured() = + let local = 0 + () => + local +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function lambda#0 @ -> Pure +//│ flow-analysis > function lambda$#0 @ -> Pure +//│ flow-analysis > function lambda$#1 @ -> Pure +//│ flow-analysis > function observe_captured#0 @ -> Pure +//│ flow-analysis > call lambda$@result @ -> Pure +//│ flow-analysis > call lambda@result @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + +// * Observing a mutable state is an effect. +// ? But are there analysis-wise difference between the following 2 cases? +let state = 0 +set state = 42 +fun observe_mutable() = + state +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe_mutable#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = 42 +let state = 0 +fun observe_mutable() = + state +set state = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe_mutable#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = 42 + + +// * Observing a state field/element is an effect. +let state = { value: 0 } +fun observe_field() = + state.value +let state = [0] +fun observe_element() = + state.[0] +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe_element#0 @ -> UnsafeEta +//│ flow-analysis > function observe_field#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = [0] + + +// * Observing a local field/element is pure. +// TODO: the same refinement as above +fun observe_local_field() = + let local = { value: 0 } + local.value +fun observe_local_element() = + let local = [0] + local.[0] +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe_local_element#0 @ -> UnsafeEta +//│ flow-analysis > function observe_local_field#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Observing an aliased field/element is an effect. +fun observe_alias_field(obj) = + let local = obj + local.value +fun observe_alias_element(xs) = + let local = xs + local.[0] +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function observe_alias_element#0 @ -> UnsafeEta +//│ flow-analysis > function observe_alias_field#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Some edge cases... +// * Spreading a tuple or record is an effect because it is equivalent to accesses. +// TODO: the same refinement as above +fun tup_spread_local() = + let xs = [42] + [...xs] +fun rec_spread_local() = + let obj = { value: 42 } + {...obj} +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function rec_spread_local#0 @ -> UnsafeEta +//│ flow-analysis > function tup_spread_local#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +let xs = [42] +fun tup_spread_nonlocal() = + [...xs] +let obj = { value: 42 } +fun rec_spread_nonlocal() = + {...obj} +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function rec_spread_nonlocal#0 @ -> UnsafeEta +//│ flow-analysis > function tup_spread_nonlocal#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ obj = {value: 42} +//│ xs = [42] + + +// * Reading a shared capture is an effect even though only the other closure writes it. +fun shared_captures() = + let local = 0 + fun observe() = + local + fun mutate() = + set local = 42 + [observe, mutate] +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate#0 @ -> UnsafeEta +//│ flow-analysis > function mutate$#0 @ -> Pure +//│ flow-analysis > function mutate$#1 @ -> UnsafeEta +//│ flow-analysis > function observe#0 @ -> UnsafeEta +//│ flow-analysis > function observe$#0 @ -> Pure +//│ flow-analysis > function observe$#1 @ -> UnsafeEta +//│ flow-analysis > function shared_captures#0 @ -> UnsafeEta +//│ flow-analysis > call mutate$@result @ -> Pure +//│ flow-analysis > call mutate@result @ -> UnsafeEta +//│ flow-analysis > call observe$@result @ -> Pure +//│ flow-analysis > call observe@result @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Conditional branches retain shared writes. +let state = 0 +fun mutate_if(cond) = + if cond do set state = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_if#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = 0 + + +// * Conditional local mutation remains pure. +fun mutate_local_if(cond) = + let local = 0 + if cond do set local = 42 + local +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_local_if#0 @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< + + +// * Loops retain shared writes. +let state = 0 +fun mutate_loop(again) = + while again do + set state = 42 + set again = false +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_loop#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +//│ state = 0 + + +// * Local mutation in a loop remains pure. +fun mutate_local_loop(again) = + let local = 0 + while again do + set local = 42 + set again = false + local +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function mutate_local_loop#0 @ -> Pure +//│ flow-analysis > <<< effect-analysis results <<< diff --git a/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls b/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls index a5b09b43c6..228347fdd3 100644 --- a/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls +++ b/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls @@ -7,13 +7,15 @@ //│ eta-expansion > <<< eta-expansion targets shapes <<< -fun effect() = print() +let state = 0 +fun effect() = set state += 42 //│ flow-analysis > >>> effect-analysis results >>> //│ flow-analysis > function effect#0 @ -> UnsafeEta -//│ flow-analysis > call print@result @ -> UnsafeEta +//│ flow-analysis > call +@result @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< +//│ state = 0 // * Pure doesn't prevent eta-expansion. @@ -54,7 +56,6 @@ node()() //│ flow-analysis > <<< effect-analysis results <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< -//│ > //│ = 42 @@ -105,5 +106,4 @@ node()()() //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > node⁰#0 @ : [0, 0] //│ eta-expansion > <<< eta-expansion targets shapes <<< -//│ > //│ = 42 From 314ec9d7df511b9c90c75b208fa07b4e3bf229a7 Mon Sep 17 00:00:00 2001 From: Flandia Date: Sun, 4 Oct 2026 14:00:14 +0800 Subject: [PATCH 7/9] Resolve Q: function divergence --- hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala index 347d9e4fb5..f1d5404a01 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/EtaExpansion.scala @@ -112,7 +112,6 @@ class EtaExpansionSolver(val constraintSolver: FlowConstraintSolver, tl: TraceLo if !processing.contains(pf) then // It'd be unsound if eta-expansion postpones the evaluation of a // function if it may have or observe (side) effects. - // TODO: function divergence? val safe = pf.effect.exists(EffectAnalysis.summarize(_) == EffectSummary.Pure) val res = targets :: (if safe then funResShape(pf.res) else Nil) cache(pf) = res From f6107a01aa3817454324584e0072ad51f6d076b6 Mon Sep 17 00:00:00 2001 From: Flandia Date: Sun, 4 Oct 2026 14:29:38 +0800 Subject: [PATCH 8/9] Show stable symbol identifiers --- .../codegen/flowAnalysis/EffectAnalysis.scala | 36 +- .../test/mlscript/codegen/ConfigDirective.mls | 6 +- .../test/mlscript/dead-param-elim/todos.mls | 60 +- .../src/test/mlscript/deforest/append.mls | 248 +- .../src/test/mlscript/deforest/basic.mls | 216 +- .../src/test/mlscript/deforest/clashes.mls | 202 +- .../src/test/mlscript/deforest/cyclic.mls | 96 +- .../test/mlscript/deforest/determinism.mls | 6 +- .../src/test/mlscript/deforest/dropLast.mls | 200 +- .../test/mlscript/deforest/erasedTypes.mls | 6 +- .../mlscript/deforest/eta-expansion/basic.mls | 92 +- .../deforest/eta-expansion/recursive.mls | 76 +- .../src/test/mlscript/deforest/fusibility.mls | 416 +-- .../src/test/mlscript/deforest/imperative.mls | 36 +- .../mlscript/deforest/listComprehension.mls | 288 +- .../src/test/mlscript/deforest/module.mls | 298 +- .../test/mlscript/deforest/multiArgLists.mls | 32 +- .../test/mlscript/deforest/nestedMatch.mls | 572 ++-- .../src/test/mlscript/deforest/recursive.mls | 2506 ++++++++--------- .../mlscript/deforest/relaxedPrograms.mls | 84 +- .../deforest/selectionsInNestedMatch.mls | 94 +- .../src/test/mlscript/deforest/simple.mls | 1550 +++++----- .../test/mlscript/deforest/stratvarNaming.mls | 38 +- .../src/test/mlscript/deforest/todos.mls | 118 +- .../src/test/mlscript/deforest/zipunzip.mls | 304 +- .../test/mlscript/effect-analysis/Basic.mls | 160 +- .../test/mlscript/effect-analysis/Imports.mls | 66 +- .../mlscript/effect-analysis/Mutation.mls | 102 +- .../src/test/mlscript/opt/EtaEffects.mls | 56 +- 29 files changed, 3979 insertions(+), 3985 deletions(-) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala index 7e596fc1e3..235261ccdd 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/EffectAnalysis.scala @@ -5,6 +5,7 @@ package flowAnalysis import hkmc2.semantics.* import hkmc2.utils.*, shorthands.* import utils.* +import scala.collection.immutable.* enum EffectSummary: @@ -27,12 +28,13 @@ object EffectAnalysis: def apply(solver: FlowConstraintSolver)(using tl: TraceLogger): EffectAnalysisResult = given fState: FlowAnalysis.State = solver.fState - given eState: Elaborator.State = solver.eState + given raise: Raise = solver.preAnalyzer.raise + given symbolPrinter: SymbolPrinter = solver.preAnalyzer.traceSymbolPrinter val result = EffectAnalysisResult( - solver.functionEffectVars.iterator.map((id, effect) => id -> summarize(effect)).toMap, - solver.callEffectVars.iterator.map((id, effect) => id -> summarize(effect)).toMap, + solver.functionEffectVars.iterator.map((id, effect) => id -> summarize(effect)).to(SeqMap), + solver.callEffectVars.iterator.map((id, effect) => id -> summarize(effect)).to(SeqMap), ) if tl.doTrace then logResult(result) @@ -42,34 +44,26 @@ object EffectAnalysis: private def logResult(result: EffectAnalysisResult)(using tl: TraceLogger, fState: FlowAnalysis.State, - eState: Elaborator.State, + symbolPrinter: SymbolPrinter, + raise: Raise, ): Unit = - def showRefSite(resultId: ResultId): Str = - resultId.getReferredFun match - case Some(fun) => s"${fun.nme}@$resultId" - case None => s"${resultId.getResult}@$resultId" - - def showInstId(instId: InstantiationId): Str = - if instId.isEmpty then "" else instId.map(showRefSite).mkString(".") + given ShowCfg = ShowCfg.internal def showFunction(id: ConcreteId[FunId]): Str = - val name = id.exprId match - case (funSym: TermSymbol, whichParamList) => s"${funSym.nme}#$whichParamList" - case exprId: ResultId => s"lambda@$exprId" - s"function $name @ ${showInstId(id.instId)}" + s"function ${id.showConcreteFunId}" def showPath(path: Path): Str = path match - case Value.SimpleRef(sym) => sym.nme - case Value.MemberRef(_, disamb) => disamb.nme + case Value.SimpleRef(sym) => symbolPrinter.printSymbol(sym) + case Value.MemberRef(_, disamb) => symbolPrinter.printSymbol(disamb) case Select(_, name) => name.name case _ => "" def showCall(id: ConcreteId[ResultId]): Str = val call = id.exprId.getResult match - case Call(fun, _) => s"call ${showPath(fun)}@${id.exprId}" - case Instantiate(_, cls, _) => s"instantiate ${showPath(cls)}@${id.exprId}" - case other => s"call $other@${id.exprId}" - s"$call @ ${showInstId(id.instId)}" + case Call(fun, _) => s"call ${showPath(fun)}@${id.exprId.showRefSite}" + case Instantiate(_, cls, _) => s"instantiate ${showPath(cls)}@${id.exprId.showRefSite}" + case other => s"call $other@${id.exprId.showRefSite}" + s"$call @ ${id.instId.showInstId}" tl.log(">>> effect-analysis results >>>") result.latentEffects.iterator.map: (id, effect) => diff --git a/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls b/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls index 246cbf4650..adcbc846ff 100644 --- a/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls +++ b/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls @@ -172,9 +172,9 @@ data class Pair(a, b) fun fstConfig(p) = if p is Pair(x, y) then x fstConfig(Pair(1, 2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function fstConfig#0 @ fstConfig@fstConfig -> UnsafeEta -//│ deforest > function fstConfig#0 @ fstConfig@fstConfig -> UnsafeEta -//│ deforest > call fstConfig@result @ -> UnsafeEta +//│ deforest > function fstConfig⁰#0 @ fstConfig² -> UnsafeEta +//│ deforest > function fstConfig⁰#0 @ fstConfig¹ -> UnsafeEta +//│ deforest > call fstConfig⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Pair⁰(1, 2) -> diff --git a/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls b/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls index 8d859f9d13..2a4513695f 100644 --- a/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls +++ b/hkmc2/shared/src/test/mlscript/dead-param-elim/todos.mls @@ -34,12 +34,12 @@ fun c(x) = r c(p(true)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> Pure -//│ deforest > function c#0 @ c@c -> Pure -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > call c@result @ -> Pure -//│ deforest > call p@result @ -> Pure +//│ deforest > function c⁰#0 @ c² -> Pure +//│ deforest > function c⁰#0 @ c¹ -> Pure +//│ deforest > function p⁰#0 @ p² -> Pure +//│ deforest > function p⁰#0 @ p¹ -> Pure +//│ deforest > call c⁰@result⁰ @ -> Pure +//│ deforest > call p⁰@result¹ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -100,24 +100,24 @@ fun sumPlus(ls) = r + 1 sumPlus(enum(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function sumPlus#0 @ sumPlus@sumPlus -> UnsafeEta -//│ deforest > function sumPlus#0 @ sumPlus@sumPlus -> UnsafeEta -//│ deforest > call +@result @ sumPlus@sumPlus -> Pure -//│ deforest > call +@result @ sumPlus@sumPlus -> Pure -//│ deforest > call +@result @ sumPlus@sumPlus -> Pure -//│ deforest > call +@result @ sumPlus@sumPlus -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call <@result @ enum@enum -> Pure -//│ deforest > call <@result @ enum@enum -> Pure -//│ deforest > call enum@result @ -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call sumPlus@result @ -> UnsafeEta -//│ deforest > call sumPlus@result @ sumPlus@sumPlus -> UnsafeEta -//│ deforest > call sumPlus@result @ sumPlus@sumPlus -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum² -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum¹ -> UnsafeEta +//│ deforest > function sumPlus⁰#0 @ sumPlus² -> UnsafeEta +//│ deforest > function sumPlus⁰#0 @ sumPlus¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ sumPlus² -> Pure +//│ deforest > call +⁰@result² @ sumPlus¹ -> Pure +//│ deforest > call +⁰@result¹ @ sumPlus² -> Pure +//│ deforest > call +⁰@result¹ @ sumPlus¹ -> Pure +//│ deforest > call -⁰@result⁴ @ enum² -> Pure +//│ deforest > call -⁰@result⁴ @ enum¹ -> Pure +//│ deforest > call <⁰@result³ @ enum² -> Pure +//│ deforest > call <⁰@result³ @ enum¹ -> Pure +//│ deforest > call enum⁰@result⁵ @ enum² -> UnsafeEta +//│ deforest > call enum⁰@result⁵ @ enum¹ -> UnsafeEta +//│ deforest > call enum⁰@result⁷ @ -> UnsafeEta +//│ deforest > call sumPlus⁰@result⁰ @ sumPlus² -> UnsafeEta +//│ deforest > call sumPlus⁰@result⁰ @ sumPlus¹ -> UnsafeEta +//│ deforest > call sumPlus⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -202,12 +202,12 @@ fun c(x) = if x is B then 2 c(p(true)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> Pure +//│ deforest > function c²#0 @ c³ -> UnsafeEta +//│ deforest > function c²#0 @ c⁴ -> UnsafeEta +//│ deforest > function p²#0 @ p³ -> Pure +//│ deforest > function p²#0 @ p⁴ -> Pure +//│ deforest > call c²@result⁰ @ -> UnsafeEta +//│ deforest > call p²@result¹ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/append.mls b/hkmc2/shared/src/test/mlscript/deforest/append.mls index a7dab33fa9..ef6b54f77f 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/append.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/append.mls @@ -26,28 +26,28 @@ appendThree of id(3 :: 4 :: Nil) id(5 :: 6 :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append1#0 @ append1@append1 -> UnsafeEta -//│ deforest > function append1#0 @ appendThree@appendThree.append1@append1 -> UnsafeEta -//│ deforest > function append1#0 @ appendThree@appendThree.append1@append1 -> UnsafeEta -//│ deforest > function append2#0 @ append2@append2 -> UnsafeEta -//│ deforest > function append2#0 @ appendThree@appendThree.append2@append2 -> UnsafeEta -//│ deforest > function append2#0 @ appendThree@appendThree.append2@append2 -> UnsafeEta -//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta -//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append1@result @ append1@append1 -> UnsafeEta -//│ deforest > call append1@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append1@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append1@result @ appendThree@appendThree.append1@append1 -> UnsafeEta -//│ deforest > call append1@result @ appendThree@appendThree.append1@append1 -> UnsafeEta -//│ deforest > call append2@result @ append2@append2 -> UnsafeEta -//│ deforest > call append2@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append2@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append2@result @ appendThree@appendThree.append2@append2 -> UnsafeEta -//│ deforest > call append2@result @ appendThree@appendThree.append2@append2 -> UnsafeEta -//│ deforest > call appendThree@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > function append1⁰#0 @ append1² -> UnsafeEta +//│ deforest > function append1⁰#0 @ appendThree².append1¹ -> UnsafeEta +//│ deforest > function append1⁰#0 @ appendThree⁰.append1¹ -> UnsafeEta +//│ deforest > function append2⁰#0 @ append2² -> UnsafeEta +//│ deforest > function append2⁰#0 @ appendThree².append2¹ -> UnsafeEta +//│ deforest > function append2⁰#0 @ appendThree⁰.append2¹ -> UnsafeEta +//│ deforest > function appendThree¹#0 @ appendThree² -> UnsafeEta +//│ deforest > function appendThree¹#0 @ appendThree⁰ -> UnsafeEta +//│ deforest > call append1⁰@result² @ append1² -> UnsafeEta +//│ deforest > call append1⁰@result² @ appendThree².append1¹ -> UnsafeEta +//│ deforest > call append1⁰@result² @ appendThree⁰.append1¹ -> UnsafeEta +//│ deforest > call append1⁰@result³ @ appendThree² -> UnsafeEta +//│ deforest > call append1⁰@result³ @ appendThree⁰ -> UnsafeEta +//│ deforest > call append2⁰@result¹ @ appendThree² -> UnsafeEta +//│ deforest > call append2⁰@result¹ @ appendThree⁰ -> UnsafeEta +//│ deforest > call append2⁰@result⁰ @ append2² -> UnsafeEta +//│ deforest > call append2⁰@result⁰ @ appendThree².append2¹ -> UnsafeEta +//│ deforest > call append2⁰@result⁰ @ appendThree⁰.append2¹ -> UnsafeEta +//│ deforest > call appendThree¹@result⁴ @ -> UnsafeEta +//│ deforest > call id@result⁵ @ -> UnsafeEta +//│ deforest > call id@result⁶ @ -> UnsafeEta +//│ deforest > call id@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -70,54 +70,54 @@ test of id(3 :: 4 :: Nil) id(5 :: 6 :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append1#0 @ append1@append1 -> UnsafeEta -//│ deforest > function append1#0 @ append2@append2.append1@append1 -> UnsafeEta -//│ deforest > function append1#0 @ test@test.append1@append1 -> UnsafeEta -//│ deforest > function append1#0 @ test@test.append1@append1 -> UnsafeEta -//│ deforest > function append1#0 @ test@test.append2@append2.append1@append1 -> UnsafeEta -//│ deforest > function append1#0 @ test@test.append2@append2.append1@append1 -> UnsafeEta -//│ deforest > function append2#0 @ append2@append2 -> UnsafeEta -//│ deforest > function append2#0 @ test@test.append2@append2 -> UnsafeEta -//│ deforest > function append2#0 @ test@test.append2@append2 -> UnsafeEta -//│ deforest > function appendReified#0 @ append2@append2.appendReified@appendReified -> UnsafeEta -//│ deforest > function appendReified#0 @ appendReified@appendReified -> UnsafeEta -//│ deforest > function appendReified#0 @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta -//│ deforest > function appendReified#0 @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta -//│ deforest > function lambda#0 @ append2@append2 -> UnsafeEta -//│ deforest > function lambda#0 @ append2@append2 -> UnsafeEta -//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta -//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta -//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta -//│ deforest > function lambda#0 @ test@test.append2@append2 -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call append1@result @ append2@append2 -> UnsafeEta -//│ deforest > call append1@result @ test@test -> UnsafeEta -//│ deforest > call append1@result @ test@test -> UnsafeEta -//│ deforest > call append1@result @ test@test.append2@append2 -> UnsafeEta -//│ deforest > call append1@result @ test@test.append2@append2 -> UnsafeEta -//│ deforest > call append2@result @ append2@append2 -> UnsafeEta -//│ deforest > call append2@result @ test@test -> UnsafeEta -//│ deforest > call append2@result @ test@test -> UnsafeEta -//│ deforest > call append2@result @ test@test.append2@append2 -> UnsafeEta -//│ deforest > call append2@result @ test@test.append2@append2 -> UnsafeEta -//│ deforest > call appendReified@result @ append2@append2 -> UnsafeEta -//│ deforest > call appendReified@result @ append2@append2.appendReified@appendReified -> UnsafeEta -//│ deforest > call appendReified@result @ appendReified@appendReified -> UnsafeEta -//│ deforest > call appendReified@result @ test@test.append2@append2 -> UnsafeEta -//│ deforest > call appendReified@result @ test@test.append2@append2 -> UnsafeEta -//│ deforest > call appendReified@result @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta -//│ deforest > call appendReified@result @ test@test.append2@append2.appendReified@appendReified -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call ys@result @ append1@append1 -> UnsafeEta -//│ deforest > call ys@result @ append2@append2.append1@append1 -> UnsafeEta -//│ deforest > call ys@result @ test@test.append1@append1 -> UnsafeEta -//│ deforest > call ys@result @ test@test.append1@append1 -> UnsafeEta -//│ deforest > call ys@result @ test@test.append2@append2.append1@append1 -> UnsafeEta -//│ deforest > call ys@result @ test@test.append2@append2.append1@append1 -> UnsafeEta +//│ deforest > function append1⁰#0 @ append1³ -> UnsafeEta +//│ deforest > function append1⁰#0 @ append2².append1¹ -> UnsafeEta +//│ deforest > function append1⁰#0 @ test².append1² -> UnsafeEta +//│ deforest > function append1⁰#0 @ test².append2¹.append1¹ -> UnsafeEta +//│ deforest > function append1⁰#0 @ test⁰.append1² -> UnsafeEta +//│ deforest > function append1⁰#0 @ test⁰.append2¹.append1¹ -> UnsafeEta +//│ deforest > function append2⁰#0 @ append2² -> UnsafeEta +//│ deforest > function append2⁰#0 @ test².append2¹ -> UnsafeEta +//│ deforest > function append2⁰#0 @ test⁰.append2¹ -> UnsafeEta +//│ deforest > function appendReified⁰#0 @ append2².appendReified¹ -> UnsafeEta +//│ deforest > function appendReified⁰#0 @ appendReified² -> UnsafeEta +//│ deforest > function appendReified⁰#0 @ test².append2¹.appendReified¹ -> UnsafeEta +//│ deforest > function appendReified⁰#0 @ test⁰.append2¹.appendReified¹ -> UnsafeEta +//│ deforest > function lambda¹#0 @ append2² -> UnsafeEta +//│ deforest > function lambda¹#0 @ test².append2¹ -> UnsafeEta +//│ deforest > function lambda¹#0 @ test⁰.append2¹ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ append2² -> UnsafeEta +//│ deforest > function lambda⁰#0 @ test².append2¹ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ test⁰.append2¹ -> UnsafeEta +//│ deforest > function test¹#0 @ test² -> UnsafeEta +//│ deforest > function test¹#0 @ test⁰ -> UnsafeEta +//│ deforest > call append1⁰@result² @ append2² -> UnsafeEta +//│ deforest > call append1⁰@result² @ test².append2¹ -> UnsafeEta +//│ deforest > call append1⁰@result² @ test⁰.append2¹ -> UnsafeEta +//│ deforest > call append1⁰@result⁶ @ test² -> UnsafeEta +//│ deforest > call append1⁰@result⁶ @ test⁰ -> UnsafeEta +//│ deforest > call append2⁰@result⁴ @ append2² -> UnsafeEta +//│ deforest > call append2⁰@result⁴ @ test².append2¹ -> UnsafeEta +//│ deforest > call append2⁰@result⁴ @ test⁰.append2¹ -> UnsafeEta +//│ deforest > call append2⁰@result⁵ @ test² -> UnsafeEta +//│ deforest > call append2⁰@result⁵ @ test⁰ -> UnsafeEta +//│ deforest > call appendReified⁰@result¹ @ append2².appendReified¹ -> UnsafeEta +//│ deforest > call appendReified⁰@result¹ @ appendReified² -> UnsafeEta +//│ deforest > call appendReified⁰@result¹ @ test².append2¹.appendReified¹ -> UnsafeEta +//│ deforest > call appendReified⁰@result¹ @ test⁰.append2¹.appendReified¹ -> UnsafeEta +//│ deforest > call appendReified⁰@result⁰ @ append2² -> UnsafeEta +//│ deforest > call appendReified⁰@result⁰ @ test².append2¹ -> UnsafeEta +//│ deforest > call appendReified⁰@result⁰ @ test⁰.append2¹ -> UnsafeEta +//│ deforest > call id@result¹⁰ @ -> UnsafeEta +//│ deforest > call id@result⁸ @ -> UnsafeEta +//│ deforest > call id@result⁹ @ -> UnsafeEta +//│ deforest > call test¹@result⁷ @ -> UnsafeEta +//│ deforest > call ys⁰@result³ @ append1³ -> UnsafeEta +//│ deforest > call ys⁰@result³ @ append2².append1¹ -> UnsafeEta +//│ deforest > call ys⁰@result³ @ test².append1² -> UnsafeEta +//│ deforest > call ys⁰@result³ @ test².append2¹.append1¹ -> UnsafeEta +//│ deforest > call ys⁰@result³ @ test⁰.append1² -> UnsafeEta +//│ deforest > call ys⁰@result³ @ test⁰.append2¹.append1¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -138,43 +138,43 @@ appendThree of id(3 :: 4 :: Nil) id(5 :: 6 :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > function append#0 @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta -//│ deforest > function appendThree#0 @ appendThree@appendThree -> UnsafeEta -//│ deforest > function idList#0 @ append@append.idList@idList -> UnsafeEta -//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > function idList#0 @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > function idList#0 @ idList@idList -> UnsafeEta -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call append@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call appendThree@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call idList@result @ append@append -> UnsafeEta -//│ deforest > call idList@result @ append@append.idList@idList -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > call idList@result @ appendThree@appendThree.append@append.idList@idList -> UnsafeEta -//│ deforest > call idList@result @ idList@idList -> UnsafeEta +//│ deforest > function appendThree¹#0 @ appendThree² -> UnsafeEta +//│ deforest > function appendThree¹#0 @ appendThree⁰ -> UnsafeEta +//│ deforest > function append⁰#0 @ appendThree².append² -> UnsafeEta +//│ deforest > function append⁰#0 @ appendThree².append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ appendThree⁰.append² -> UnsafeEta +//│ deforest > function append⁰#0 @ appendThree⁰.append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ append³ -> UnsafeEta +//│ deforest > function idList⁰#0 @ appendThree².append².idList¹ -> UnsafeEta +//│ deforest > function idList⁰#0 @ appendThree².append¹.idList¹ -> UnsafeEta +//│ deforest > function idList⁰#0 @ appendThree⁰.append².idList¹ -> UnsafeEta +//│ deforest > function idList⁰#0 @ appendThree⁰.append¹.idList¹ -> UnsafeEta +//│ deforest > function idList⁰#0 @ append³.idList¹ -> UnsafeEta +//│ deforest > function idList⁰#0 @ idList² -> UnsafeEta +//│ deforest > call appendThree¹@result⁵ @ -> UnsafeEta +//│ deforest > call append⁰@result² @ appendThree².append² -> UnsafeEta +//│ deforest > call append⁰@result² @ appendThree².append¹ -> UnsafeEta +//│ deforest > call append⁰@result² @ appendThree⁰.append² -> UnsafeEta +//│ deforest > call append⁰@result² @ appendThree⁰.append¹ -> UnsafeEta +//│ deforest > call append⁰@result² @ append³ -> UnsafeEta +//│ deforest > call append⁰@result³ @ appendThree² -> UnsafeEta +//│ deforest > call append⁰@result³ @ appendThree⁰ -> UnsafeEta +//│ deforest > call append⁰@result⁴ @ appendThree² -> UnsafeEta +//│ deforest > call append⁰@result⁴ @ appendThree⁰ -> UnsafeEta +//│ deforest > call id@result⁶ @ -> UnsafeEta +//│ deforest > call id@result⁷ @ -> UnsafeEta +//│ deforest > call id@result⁸ @ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ appendThree².append².idList¹ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ appendThree².append¹.idList¹ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ appendThree⁰.append².idList¹ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ appendThree⁰.append¹.idList¹ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ append³.idList¹ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ idList² -> UnsafeEta +//│ deforest > call idList⁰@result⁰ @ appendThree².append² -> UnsafeEta +//│ deforest > call idList⁰@result⁰ @ appendThree².append¹ -> UnsafeEta +//│ deforest > call idList⁰@result⁰ @ appendThree⁰.append² -> UnsafeEta +//│ deforest > call idList⁰@result⁰ @ appendThree⁰.append¹ -> UnsafeEta +//│ deforest > call idList⁰@result⁰ @ append³ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h⁰, tmp⁰) -> @@ -214,23 +214,23 @@ concat of id of (3 :: 4 :: Nil) :: (5 :: 6 :: Nil) :: Nil //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ concat@concat.append@append -> UnsafeEta -//│ deforest > function append#0 @ concat@concat.append@append -> UnsafeEta -//│ deforest > function concat#0 @ concat@concat -> UnsafeEta -//│ deforest > function concat#0 @ concat@concat -> UnsafeEta -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ concat@concat -> UnsafeEta -//│ deforest > call append@result @ concat@concat -> UnsafeEta -//│ deforest > call append@result @ concat@concat.append@append -> UnsafeEta -//│ deforest > call append@result @ concat@concat.append@append -> UnsafeEta -//│ deforest > call concat@result @ -> UnsafeEta -//│ deforest > call concat@result @ concat@concat -> UnsafeEta -//│ deforest > call concat@result @ concat@concat -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call idList@result @ append@append -> UnsafeEta -//│ deforest > call idList@result @ concat@concat.append@append -> UnsafeEta -//│ deforest > call idList@result @ concat@concat.append@append -> UnsafeEta +//│ deforest > function append⁰#0 @ append² -> UnsafeEta +//│ deforest > function append⁰#0 @ concat².append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ concat⁰.append¹ -> UnsafeEta +//│ deforest > function concat¹#0 @ concat² -> UnsafeEta +//│ deforest > function concat¹#0 @ concat⁰ -> UnsafeEta +//│ deforest > call append⁰@result² @ append² -> UnsafeEta +//│ deforest > call append⁰@result² @ concat².append¹ -> UnsafeEta +//│ deforest > call append⁰@result² @ concat⁰.append¹ -> UnsafeEta +//│ deforest > call append⁰@result³ @ concat² -> UnsafeEta +//│ deforest > call append⁰@result³ @ concat⁰ -> UnsafeEta +//│ deforest > call concat¹@result⁰ @ concat² -> UnsafeEta +//│ deforest > call concat¹@result⁰ @ concat⁰ -> UnsafeEta +//│ deforest > call concat¹@result⁴ @ -> UnsafeEta +//│ deforest > call id@result⁵ @ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ append² -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ concat².append¹ -> UnsafeEta +//│ deforest > call idList⁰@result¹ @ concat⁰.append¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< diff --git a/hkmc2/shared/src/test/mlscript/deforest/basic.mls b/hkmc2/shared/src/test/mlscript/deforest/basic.mls index 80f23e21c1..525ff30a6c 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/basic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/basic.mls @@ -55,12 +55,12 @@ fun c(x) = if x is X(x) then x c(p()) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(O⁰) -> @@ -77,12 +77,12 @@ fun f(x) = if x is X(Y(y)) then y f(p()) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp⁰) -> @@ -163,14 +163,14 @@ fun f(x, res) = if x is Y(y) then res + tmp f(p(), 2) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > function p²#0 @ p³ -> UnsafeEta +//│ deforest > function p²#0 @ p⁴ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call f²@result¹ @ -> UnsafeEta +//│ deforest > call p²@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp¹) -> @@ -194,15 +194,15 @@ fun f(x, y, res) = if x is res + tmp + a f(X(1), Y(2), 3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function _d#0 @ f@f -> UnsafeEta -//│ deforest > function _d#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function _d⁰#0 @ f² -> UnsafeEta +//│ deforest > function _d⁰#0 @ f⁴ -> UnsafeEta +//│ deforest > function f³#0 @ f² -> UnsafeEta +//│ deforest > function f³#0 @ f⁴ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ f² -> Pure +//│ deforest > call +⁰@result¹ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call f³@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(1) -> @@ -217,16 +217,16 @@ fun c(x, d) = if x is X(a) then c(X(a), d) () => c(X(3), 2) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ lambda@lambda.c@c -> UnsafeEta -//│ deforest > function c#0 @ lambda@lambda.c@c -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta -//│ deforest > call c@result @ c@c -> UnsafeEta -//│ deforest > call c@result @ lambda@lambda -> UnsafeEta -//│ deforest > call c@result @ lambda@lambda -> UnsafeEta -//│ deforest > call c@result @ lambda@lambda.c@c -> UnsafeEta -//│ deforest > call c@result @ lambda@lambda.c@c -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ lambda².c¹ -> UnsafeEta +//│ deforest > function c⁰#0 @ lambda⁰.c¹ -> UnsafeEta +//│ deforest > function lambda¹#0 @ lambda² -> UnsafeEta +//│ deforest > function lambda¹#0 @ lambda⁰ -> UnsafeEta +//│ deforest > call c⁰@result¹ @ lambda² -> UnsafeEta +//│ deforest > call c⁰@result¹ @ lambda⁰ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ c² -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ lambda².c¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ lambda⁰.c¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(a²) -> @@ -253,24 +253,24 @@ fun p(x) = if x is O then 2 p(c()) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function a#0 @ a@a -> Pure -//│ deforest > function a#0 @ b@b.a@a -> Pure -//│ deforest > function a#0 @ c@c.b@b.a@a -> Pure -//│ deforest > function a#0 @ c@c.b@b.a@a -> Pure -//│ deforest > function b#0 @ b@b -> Pure -//│ deforest > function b#0 @ c@c.b@b -> Pure -//│ deforest > function b#0 @ c@c.b@b -> Pure -//│ deforest > function c#0 @ c@c -> Pure -//│ deforest > function c#0 @ c@c -> Pure -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call a@result @ b@b -> Pure -//│ deforest > call a@result @ c@c.b@b -> Pure -//│ deforest > call a@result @ c@c.b@b -> Pure -//│ deforest > call b@result @ c@c -> Pure -//│ deforest > call b@result @ c@c -> Pure -//│ deforest > call c@result @ -> Pure -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function a³#0 @ a⁵ -> Pure +//│ deforest > function a³#0 @ b³.a⁴ -> Pure +//│ deforest > function a³#0 @ c².b².a⁴ -> Pure +//│ deforest > function a³#0 @ c⁰.b².a⁴ -> Pure +//│ deforest > function b¹#0 @ b³ -> Pure +//│ deforest > function b¹#0 @ c².b² -> Pure +//│ deforest > function b¹#0 @ c⁰.b² -> Pure +//│ deforest > function c¹#0 @ c² -> Pure +//│ deforest > function c¹#0 @ c⁰ -> Pure +//│ deforest > function p²#0 @ p³ -> UnsafeEta +//│ deforest > function p²#0 @ p⁴ -> UnsafeEta +//│ deforest > call a³@result⁰ @ b³ -> Pure +//│ deforest > call a³@result⁰ @ c².b² -> Pure +//│ deforest > call a³@result⁰ @ c⁰.b² -> Pure +//│ deforest > call b¹@result¹ @ c² -> Pure +//│ deforest > call b¹@result¹ @ c⁰ -> Pure +//│ deforest > call c¹@result³ @ -> Pure +//│ deforest > call p²@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > O⁰ -> @@ -284,7 +284,7 @@ p(c()) if [1, 2] is [a, b] then a + b //│ deforest > >>> effect-analysis results >>> -//│ deforest > call +@result @ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [1, 2] -> @@ -319,11 +319,11 @@ fun f(x) = if x is [a,b] then a + b f([1,2]) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call f²@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [1, 2] -> @@ -339,10 +339,10 @@ fun f(x) = if x is O then 2 f(id(O)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call f²@result⁰ @ -> UnsafeEta +//│ deforest > call id@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -356,9 +356,9 @@ fun f() = O then 0 f() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call f²@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -371,9 +371,9 @@ fun f(x) = if x is A(x) then x f(A(1)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call f²@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(1) -> @@ -388,11 +388,11 @@ fun f(x) = if x is A(a) then x.A#x + a f(A(1)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call f²@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(1) -> @@ -408,12 +408,12 @@ fun f(x) = if x is A(x) then 2 f(A(2)) + f(A(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > function f²#0 @ f⁵ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call f²@result² @ -> UnsafeEta +//│ deforest > call f²@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(3) -> @@ -433,11 +433,11 @@ if localFuse(3) is B(a) then a localFuse(4) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function localFuse#0 @ localFuse@localFuse -> UnsafeEta -//│ deforest > function localFuse#0 @ localFuse@localFuse -> UnsafeEta -//│ deforest > function localFuse#0 @ localFuse@localFuse -> UnsafeEta -//│ deforest > call localFuse@result @ -> UnsafeEta -//│ deforest > call localFuse@result @ -> UnsafeEta +//│ deforest > function localFuse⁰#0 @ localFuse² -> UnsafeEta +//│ deforest > function localFuse⁰#0 @ localFuse³ -> UnsafeEta +//│ deforest > function localFuse⁰#0 @ localFuse¹ -> UnsafeEta +//│ deforest > call localFuse⁰@result¹ @ -> UnsafeEta +//│ deforest > call localFuse⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(x¹¹) -> @@ -465,14 +465,14 @@ fun f(x) = x.A#x let o = A(1) g(o) + f(o) + o.A#x //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call f²@result² @ -> UnsafeEta +//│ deforest > call g⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -486,8 +486,8 @@ let x = if A(0) is let f() = x f() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ -> UnsafeEta +//│ deforest > call f³@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(0) -> @@ -500,7 +500,7 @@ f() :fixme f() //│ deforest > >>> effect-analysis results >>> -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > call f²@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -514,14 +514,14 @@ fun dtor(x) = if x is A then inner(B(4), x.A#x) dtor(A(B(0))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function dtor#0 @ dtor@dtor -> UnsafeEta -//│ deforest > function dtor#0 @ dtor@dtor -> UnsafeEta -//│ deforest > function inner#0 @ dtor@dtor.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ dtor@dtor.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ inner@inner -> UnsafeEta -//│ deforest > call dtor@result @ -> UnsafeEta -//│ deforest > call inner@result @ dtor@dtor -> UnsafeEta -//│ deforest > call inner@result @ dtor@dtor -> UnsafeEta +//│ deforest > function dtor¹#0 @ dtor² -> UnsafeEta +//│ deforest > function dtor¹#0 @ dtor⁰ -> UnsafeEta +//│ deforest > function inner⁰#0 @ dtor².inner¹ -> UnsafeEta +//│ deforest > function inner⁰#0 @ dtor⁰.inner¹ -> UnsafeEta +//│ deforest > function inner⁰#0 @ inner² -> UnsafeEta +//│ deforest > call dtor¹@result¹ @ -> UnsafeEta +//│ deforest > call inner⁰@result⁰ @ dtor² -> UnsafeEta +//│ deforest > call inner⁰@result⁰ @ dtor⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰(4) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/clashes.mls b/hkmc2/shared/src/test/mlscript/deforest/clashes.mls index 508bec38b5..1e5181b4b7 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/clashes.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/clashes.mls @@ -31,54 +31,54 @@ fun badWrap(n) = x f1(badWrap(4)) + f2(badWrap(5)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function badWrap#0 @ badWrap@badWrap -> UnsafeEta -//│ deforest > function badWrap#0 @ badWrap@badWrap -> UnsafeEta -//│ deforest > function badWrap#0 @ badWrap@badWrap -> UnsafeEta -//│ deforest > function f1#0 @ badWrap@badWrap.f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ badWrap@badWrap.f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ badWrap@badWrap.f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ badWrap@badWrap.f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ badWrap@badWrap.f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ badWrap@badWrap.f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function to#0 @ badWrap@badWrap.to@to -> UnsafeEta -//│ deforest > function to#0 @ badWrap@badWrap.to@to -> UnsafeEta -//│ deforest > function to#0 @ badWrap@badWrap.to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ badWrap@badWrap.f2@f2 -> Pure -//│ deforest > call +@result @ badWrap@badWrap.f2@f2 -> Pure -//│ deforest > call +@result @ badWrap@badWrap.f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call -@result @ badWrap@badWrap.to@to -> Pure -//│ deforest > call -@result @ badWrap@badWrap.to@to -> Pure -//│ deforest > call -@result @ badWrap@badWrap.to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call >@result @ badWrap@badWrap.to@to -> Pure -//│ deforest > call >@result @ badWrap@badWrap.to@to -> Pure -//│ deforest > call >@result @ badWrap@badWrap.to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call badWrap@result @ -> UnsafeEta -//│ deforest > call badWrap@result @ -> UnsafeEta -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f1@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call f1@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call f1@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call f2@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call f2@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call f2@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call to@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call to@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call to@result @ badWrap@badWrap -> UnsafeEta -//│ deforest > call to@result @ badWrap@badWrap.to@to -> UnsafeEta -//│ deforest > call to@result @ badWrap@badWrap.to@to -> UnsafeEta -//│ deforest > call to@result @ badWrap@badWrap.to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > function badWrap¹#0 @ badWrap² -> UnsafeEta +//│ deforest > function badWrap¹#0 @ badWrap³ -> UnsafeEta +//│ deforest > function badWrap¹#0 @ badWrap⁰ -> UnsafeEta +//│ deforest > function f1⁰#0 @ badWrap².f1¹ -> UnsafeEta +//│ deforest > function f1⁰#0 @ badWrap³.f1¹ -> UnsafeEta +//│ deforest > function f1⁰#0 @ badWrap⁰.f1¹ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1³ -> UnsafeEta +//│ deforest > function f2⁰#0 @ badWrap².f2¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ badWrap³.f2¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ badWrap⁰.f2¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2³ -> UnsafeEta +//│ deforest > function to⁰#0 @ badWrap².to¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ badWrap³.to¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ badWrap⁰.to¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ to² -> UnsafeEta +//│ deforest > call +⁰@result⁵ @ badWrap².f2¹ -> Pure +//│ deforest > call +⁰@result⁵ @ badWrap³.f2¹ -> Pure +//│ deforest > call +⁰@result⁵ @ badWrap⁰.f2¹ -> Pure +//│ deforest > call +⁰@result⁵ @ f2² -> Pure +//│ deforest > call +⁰@result⁵ @ f2³ -> Pure +//│ deforest > call +⁰@result⁷ @ -> Pure +//│ deforest > call -⁰@result¹ @ badWrap².to¹ -> Pure +//│ deforest > call -⁰@result¹ @ badWrap³.to¹ -> Pure +//│ deforest > call -⁰@result¹ @ badWrap⁰.to¹ -> Pure +//│ deforest > call -⁰@result¹ @ to² -> Pure +//│ deforest > call >⁰@result² @ badWrap².to¹ -> Pure +//│ deforest > call >⁰@result² @ badWrap³.to¹ -> Pure +//│ deforest > call >⁰@result² @ badWrap⁰.to¹ -> Pure +//│ deforest > call >⁰@result² @ to² -> Pure +//│ deforest > call badWrap¹@result¹¹ @ -> UnsafeEta +//│ deforest > call badWrap¹@result⁹ @ -> UnsafeEta +//│ deforest > call f1⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call f1⁰@result⁴ @ badWrap² -> UnsafeEta +//│ deforest > call f1⁰@result⁴ @ badWrap³ -> UnsafeEta +//│ deforest > call f1⁰@result⁴ @ badWrap⁰ -> UnsafeEta +//│ deforest > call f2⁰@result⁶ @ badWrap² -> UnsafeEta +//│ deforest > call f2⁰@result⁶ @ badWrap³ -> UnsafeEta +//│ deforest > call f2⁰@result⁶ @ badWrap⁰ -> UnsafeEta +//│ deforest > call f2⁰@result⁸ @ -> UnsafeEta +//│ deforest > call to⁰@result³ @ badWrap² -> UnsafeEta +//│ deforest > call to⁰@result³ @ badWrap³ -> UnsafeEta +//│ deforest > call to⁰@result³ @ badWrap⁰ -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ badWrap².to¹ -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ badWrap³.to¹ -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ badWrap⁰.to¹ -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ to² -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -95,26 +95,26 @@ fun f1(p) = if p is A(a) then a + 1 fun f2(p) = if p is A(b) then b + 2 f1(one) + f2(one) + f2(two) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2³ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p³ -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ f1² -> Pure +//│ deforest > call +⁰@result¹ @ f1¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f2² -> Pure +//│ deforest > call +⁰@result⁰ @ f2³ -> Pure +//│ deforest > call +⁰@result⁰ @ f2¹ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call f1⁰@result⁶ @ -> UnsafeEta +//│ deforest > call f2⁰@result³ @ -> UnsafeEta +//│ deforest > call f2⁰@result⁵ @ -> UnsafeEta +//│ deforest > call p⁰@result⁷ @ -> UnsafeEta +//│ deforest > call p⁰@result⁸ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(x⁰) -> @@ -137,25 +137,25 @@ let res3 = p(y) // y flows into this call-site result // f1(res1) + f2(res1) + f1(res2) + f2(res3) f1(res1) + f1(res2) + f2(res3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call p@result @ -> Pure -//│ deforest > call p@result @ -> Pure -//│ deforest > call p@result @ -> Pure +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1³ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function p¹#0 @ p² -> Pure +//│ deforest > function p¹#0 @ p³ -> Pure +//│ deforest > function p¹#0 @ p⁴ -> Pure +//│ deforest > function p¹#0 @ p⁵ -> Pure +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ f2² -> Pure +//│ deforest > call +⁰@result⁰ @ f2¹ -> Pure +//│ deforest > call f1⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f1⁰@result⁵ @ -> UnsafeEta +//│ deforest > call f2⁰@result² @ -> UnsafeEta +//│ deforest > call p¹@result⁶ @ -> Pure +//│ deforest > call p¹@result⁷ @ -> Pure +//│ deforest > call p¹@result⁸ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -177,20 +177,20 @@ fun p(x, clashedCtor) = let clashed = A(3) f1(p(1, clashed)) + f2(p(2, clashed)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function p¹#0 @ p² -> UnsafeEta +//│ deforest > function p¹#0 @ p³ -> UnsafeEta +//│ deforest > function p¹#0 @ p⁴ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ f2² -> Pure +//│ deforest > call +⁰@result⁰ @ f2¹ -> Pure +//│ deforest > call f1⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f2⁰@result² @ -> UnsafeEta +//│ deforest > call p¹@result³ @ -> UnsafeEta +//│ deforest > call p¹@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< diff --git a/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls b/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls index 482b04113b..d452bc317d 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/cyclic.mls @@ -42,14 +42,14 @@ fun f(a) = if a is else D (x => 0)(f(f(C))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > call f@result @ -> Pure -//│ deforest > call f@result @ -> Pure -//│ deforest > call lambda@result @ -> Pure +//│ deforest > function f⁰#0 @ f² -> Pure +//│ deforest > function f⁰#0 @ f³ -> Pure +//│ deforest > function f⁰#0 @ f¹ -> Pure +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > call f⁰@result² @ -> Pure +//│ deforest > call f⁰@result¹ @ -> Pure +//│ deforest > call lambda⁰@result⁰ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > C⁰ -> @@ -72,14 +72,14 @@ fun maxOpt(ls) = if ls is Some(m) then if m > h then Some(m) else Some(h) maxOpt(id(1 :: 2 :: Nil)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function maxOpt#0 @ maxOpt@maxOpt -> UnsafeEta -//│ deforest > function maxOpt#0 @ maxOpt@maxOpt -> UnsafeEta -//│ deforest > call >@result @ maxOpt@maxOpt -> Pure -//│ deforest > call >@result @ maxOpt@maxOpt -> Pure -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call maxOpt@result @ -> UnsafeEta -//│ deforest > call maxOpt@result @ maxOpt@maxOpt -> UnsafeEta -//│ deforest > call maxOpt@result @ maxOpt@maxOpt -> UnsafeEta +//│ deforest > function maxOpt⁰#0 @ maxOpt² -> UnsafeEta +//│ deforest > function maxOpt⁰#0 @ maxOpt¹ -> UnsafeEta +//│ deforest > call >⁰@result¹ @ maxOpt² -> Pure +//│ deforest > call >⁰@result¹ @ maxOpt¹ -> Pure +//│ deforest > call id@result³ @ -> UnsafeEta +//│ deforest > call maxOpt⁰@result² @ -> UnsafeEta +//│ deforest > call maxOpt⁰@result⁰ @ maxOpt² -> UnsafeEta +//│ deforest > call maxOpt⁰@result⁰ @ maxOpt¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -96,15 +96,15 @@ fun modSome(x, m) = if x is None then None modSome(Some(17), 3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function modSome#0 @ modSome@modSome -> UnsafeEta -//│ deforest > function modSome#0 @ modSome@modSome -> UnsafeEta -//│ deforest > call -@result @ modSome@modSome -> Pure -//│ deforest > call -@result @ modSome@modSome -> Pure -//│ deforest > call >=@result @ modSome@modSome -> Pure -//│ deforest > call >=@result @ modSome@modSome -> Pure -//│ deforest > call modSome@result @ -> UnsafeEta -//│ deforest > call modSome@result @ modSome@modSome -> UnsafeEta -//│ deforest > call modSome@result @ modSome@modSome -> UnsafeEta +//│ deforest > function modSome⁰#0 @ modSome² -> UnsafeEta +//│ deforest > function modSome⁰#0 @ modSome¹ -> UnsafeEta +//│ deforest > call -⁰@result¹ @ modSome² -> Pure +//│ deforest > call -⁰@result¹ @ modSome¹ -> Pure +//│ deforest > call >=⁰@result⁰ @ modSome² -> Pure +//│ deforest > call >=⁰@result⁰ @ modSome¹ -> Pure +//│ deforest > call modSome⁰@result² @ modSome² -> UnsafeEta +//│ deforest > call modSome⁰@result² @ modSome¹ -> UnsafeEta +//│ deforest > call modSome⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Some⁰(tmp⁰) -> @@ -170,18 +170,18 @@ fun maxOpt2(ls, x) = if ls is else maxOpt2(t, Some(m)) maxOpt2(id(1 :: 2 :: 3 :: Nil), None) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function maxOpt2#0 @ maxOpt2@maxOpt2 -> UnsafeEta -//│ deforest > function maxOpt2#0 @ maxOpt2@maxOpt2 -> UnsafeEta -//│ deforest > call >@result @ maxOpt2@maxOpt2 -> Pure -//│ deforest > call >@result @ maxOpt2@maxOpt2 -> Pure -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call maxOpt2@result @ -> UnsafeEta -//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta -//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta -//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta -//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta -//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta -//│ deforest > call maxOpt2@result @ maxOpt2@maxOpt2 -> UnsafeEta +//│ deforest > function maxOpt2⁰#0 @ maxOpt2² -> UnsafeEta +//│ deforest > function maxOpt2⁰#0 @ maxOpt2¹ -> UnsafeEta +//│ deforest > call >⁰@result¹ @ maxOpt2² -> Pure +//│ deforest > call >⁰@result¹ @ maxOpt2¹ -> Pure +//│ deforest > call id@result⁵ @ -> UnsafeEta +//│ deforest > call maxOpt2⁰@result² @ maxOpt2² -> UnsafeEta +//│ deforest > call maxOpt2⁰@result² @ maxOpt2¹ -> UnsafeEta +//│ deforest > call maxOpt2⁰@result³ @ maxOpt2² -> UnsafeEta +//│ deforest > call maxOpt2⁰@result³ @ maxOpt2¹ -> UnsafeEta +//│ deforest > call maxOpt2⁰@result⁰ @ maxOpt2² -> UnsafeEta +//│ deforest > call maxOpt2⁰@result⁰ @ maxOpt2¹ -> UnsafeEta +//│ deforest > call maxOpt2⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -194,17 +194,17 @@ fun zipWith(xsys, f) = if xsys is [Nil, Nil] then Nil zipWith([id(Nil), id(Nil)], (x, y) => x) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function zipWith#0 @ zipWith@zipWith -> UnsafeEta -//│ deforest > function zipWith#0 @ zipWith@zipWith -> UnsafeEta -//│ deforest > call f@result @ zipWith@zipWith -> Pure -//│ deforest > call f@result @ zipWith@zipWith -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call zipWith@result @ -> UnsafeEta -//│ deforest > call zipWith@result @ zipWith@zipWith -> UnsafeEta -//│ deforest > call zipWith@result @ zipWith@zipWith -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function zipWith⁰#0 @ zipWith² -> UnsafeEta +//│ deforest > function zipWith⁰#0 @ zipWith¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ zipWith² -> Pure +//│ deforest > call f⁰@result⁰ @ zipWith¹ -> UnsafeEta +//│ deforest > call id@result³ @ -> UnsafeEta +//│ deforest > call id@result⁴ @ -> UnsafeEta +//│ deforest > call zipWith⁰@result² @ -> UnsafeEta +//│ deforest > call zipWith⁰@result¹ @ zipWith² -> UnsafeEta +//│ deforest > call zipWith⁰@result¹ @ zipWith¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [tx⁰, ty⁰] -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/determinism.mls b/hkmc2/shared/src/test/mlscript/deforest/determinism.mls index 13c08a2cb1..fc2b614e17 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/determinism.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/determinism.mls @@ -57,9 +57,9 @@ fun c2(x) = if x is A(A(A(A(A(A(a)))))) then a c2 of A(A(A(A(A(A(1)))))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2¹ -> UnsafeEta +//│ deforest > call c2⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰(tmp⁰) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls b/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls index 30619cf2ce..d38e4ee3fd 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/dropLast.mls @@ -23,20 +23,20 @@ fun fix(x) = fix(res) fix //│ deforest > >>> effect-analysis results >>> -//│ deforest > function dl#0 @ dl@dl -> UnsafeEta -//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > call dl@result @ dl@dl -> UnsafeEta -//│ deforest > call dl@result @ fix@fix -> UnsafeEta -//│ deforest > call dl@result @ fix@fix -> UnsafeEta -//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta -//│ deforest > call lseq@result @ fix@fix -> UnsafeEta -//│ deforest > call lseq@result @ fix@fix -> UnsafeEta +//│ deforest > function dl⁰#0 @ dl² -> UnsafeEta +//│ deforest > function dl⁰#0 @ fix².dl¹ -> UnsafeEta +//│ deforest > function dl⁰#0 @ fix⁰.dl¹ -> UnsafeEta +//│ deforest > function fix¹#0 @ fix² -> UnsafeEta +//│ deforest > function fix¹#0 @ fix⁰ -> UnsafeEta +//│ deforest > call dl⁰@result¹ @ fix² -> UnsafeEta +//│ deforest > call dl⁰@result¹ @ fix⁰ -> UnsafeEta +//│ deforest > call dl⁰@result⁰ @ dl² -> UnsafeEta +//│ deforest > call dl⁰@result⁰ @ fix².dl¹ -> UnsafeEta +//│ deforest > call dl⁰@result⁰ @ fix⁰.dl¹ -> UnsafeEta +//│ deforest > call fix¹@result³ @ fix² -> UnsafeEta +//│ deforest > call fix¹@result³ @ fix⁰ -> UnsafeEta +//│ deforest > call lseq⁰@result² @ fix² -> UnsafeEta +//│ deforest > call lseq⁰@result² @ fix⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -57,22 +57,22 @@ fun fix(x, fuel) = fix(res, fuel - 1) fix //│ deforest > >>> effect-analysis results >>> -//│ deforest > function dl#0 @ dl@dl -> UnsafeEta -//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > call -@result @ fix@fix -> Pure -//│ deforest > call -@result @ fix@fix -> Pure -//│ deforest > call dl@result @ dl@dl -> UnsafeEta -//│ deforest > call dl@result @ fix@fix -> UnsafeEta -//│ deforest > call dl@result @ fix@fix -> UnsafeEta -//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > call dl@result @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > call equals@result @ fix@fix -> UnsafeEta -//│ deforest > call equals@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > function dl⁰#0 @ dl² -> UnsafeEta +//│ deforest > function dl⁰#0 @ fix².dl¹ -> UnsafeEta +//│ deforest > function dl⁰#0 @ fix⁰.dl¹ -> UnsafeEta +//│ deforest > function fix¹#0 @ fix² -> UnsafeEta +//│ deforest > function fix¹#0 @ fix⁰ -> UnsafeEta +//│ deforest > call -⁰@result³ @ fix² -> Pure +//│ deforest > call -⁰@result³ @ fix⁰ -> Pure +//│ deforest > call dl⁰@result¹ @ fix² -> UnsafeEta +//│ deforest > call dl⁰@result¹ @ fix⁰ -> UnsafeEta +//│ deforest > call dl⁰@result⁰ @ dl² -> UnsafeEta +//│ deforest > call dl⁰@result⁰ @ fix².dl¹ -> UnsafeEta +//│ deforest > call dl⁰@result⁰ @ fix⁰.dl¹ -> UnsafeEta +//│ deforest > call equals@result² @ fix² -> UnsafeEta +//│ deforest > call equals@result² @ fix⁰ -> UnsafeEta +//│ deforest > call fix¹@result⁴ @ fix² -> UnsafeEta +//│ deforest > call fix¹@result⁴ @ fix⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -94,30 +94,30 @@ fun fix(x, fuel) = fix(res, fuel - 1) fix //│ deforest > >>> effect-analysis results >>> -//│ deforest > function dl#0 @ dl@dl -> UnsafeEta -//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > function dl#0 @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > function dlHelper#0 @ dl@dl.dlHelper@dlHelper -> UnsafeEta -//│ deforest > function dlHelper#0 @ dlHelper@dlHelper -> UnsafeEta -//│ deforest > function dlHelper#0 @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta -//│ deforest > function dlHelper#0 @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > call -@result @ fix@fix -> Pure -//│ deforest > call -@result @ fix@fix -> Pure -//│ deforest > call dl@result @ fix@fix -> UnsafeEta -//│ deforest > call dl@result @ fix@fix -> UnsafeEta -//│ deforest > call dlHelper@result @ dl@dl -> UnsafeEta -//│ deforest > call dlHelper@result @ dl@dl.dlHelper@dlHelper -> UnsafeEta -//│ deforest > call dlHelper@result @ dlHelper@dlHelper -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dl@dl -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dl@dl.dlHelper@dlHelper -> UnsafeEta -//│ deforest > call equals@result @ fix@fix -> UnsafeEta -//│ deforest > call equals@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ dlHelper² -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ dl².dlHelper¹ -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ fix².dl¹.dlHelper¹ -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ fix⁰.dl¹.dlHelper¹ -> UnsafeEta +//│ deforest > function dl⁰#0 @ dl² -> UnsafeEta +//│ deforest > function dl⁰#0 @ fix².dl¹ -> UnsafeEta +//│ deforest > function dl⁰#0 @ fix⁰.dl¹ -> UnsafeEta +//│ deforest > function fix¹#0 @ fix² -> UnsafeEta +//│ deforest > function fix¹#0 @ fix⁰ -> UnsafeEta +//│ deforest > call -⁰@result⁴ @ fix² -> Pure +//│ deforest > call -⁰@result⁴ @ fix⁰ -> Pure +//│ deforest > call dlHelper⁰@result¹ @ dlHelper² -> UnsafeEta +//│ deforest > call dlHelper⁰@result¹ @ dl².dlHelper¹ -> UnsafeEta +//│ deforest > call dlHelper⁰@result¹ @ fix².dl¹.dlHelper¹ -> UnsafeEta +//│ deforest > call dlHelper⁰@result¹ @ fix⁰.dl¹.dlHelper¹ -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ dl² -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ fix².dl¹ -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ fix⁰.dl¹ -> UnsafeEta +//│ deforest > call dl⁰@result² @ fix² -> UnsafeEta +//│ deforest > call dl⁰@result² @ fix⁰ -> UnsafeEta +//│ deforest > call equals@result³ @ fix² -> UnsafeEta +//│ deforest > call equals@result³ @ fix⁰ -> UnsafeEta +//│ deforest > call fix¹@result⁵ @ fix² -> UnsafeEta +//│ deforest > call fix¹@result⁵ @ fix⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -138,24 +138,24 @@ fun fix(x, fuel) = fix(res, fuel - 1) id(fix(Nil, 1000)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function dlHelper#0 @ dlHelper@dlHelper -> UnsafeEta -//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > call -@result @ fix@fix -> Pure -//│ deforest > call -@result @ fix@fix -> Pure -//│ deforest > call dlHelper@result @ dlHelper@dlHelper -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > call equals@result @ fix@fix -> UnsafeEta -//│ deforest > call equals@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ dlHelper² -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ fix².dlHelper¹ -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ fix⁰.dlHelper¹ -> UnsafeEta +//│ deforest > function fix¹#0 @ fix² -> UnsafeEta +//│ deforest > function fix¹#0 @ fix⁰ -> UnsafeEta +//│ deforest > call -⁰@result³ @ fix² -> Pure +//│ deforest > call -⁰@result³ @ fix⁰ -> Pure +//│ deforest > call dlHelper⁰@result¹ @ fix² -> UnsafeEta +//│ deforest > call dlHelper⁰@result¹ @ fix⁰ -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ dlHelper² -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ fix².dlHelper¹ -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ fix⁰.dlHelper¹ -> UnsafeEta +//│ deforest > call equals@result² @ fix² -> UnsafeEta +//│ deforest > call equals@result² @ fix⁰ -> UnsafeEta +//│ deforest > call fix¹@result⁴ @ fix² -> UnsafeEta +//│ deforest > call fix¹@result⁴ @ fix⁰ -> UnsafeEta +//│ deforest > call fix¹@result⁶ @ -> UnsafeEta +//│ deforest > call id@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -176,19 +176,19 @@ fun fix(x) = x :: xs then fix(dlHelper(x, xs)) fix(2 :: 3 :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function dlHelper#0 @ dlHelper@dlHelper -> UnsafeEta -//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > function dlHelper#0 @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > function fix#0 @ fix@fix -> UnsafeEta -//│ deforest > call dlHelper@result @ dlHelper@dlHelper -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > call dlHelper@result @ fix@fix.dlHelper@dlHelper -> UnsafeEta -//│ deforest > call fix@result @ -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta -//│ deforest > call fix@result @ fix@fix -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ dlHelper² -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ fix².dlHelper¹ -> UnsafeEta +//│ deforest > function dlHelper⁰#0 @ fix⁰.dlHelper¹ -> UnsafeEta +//│ deforest > function fix¹#0 @ fix² -> UnsafeEta +//│ deforest > function fix¹#0 @ fix⁰ -> UnsafeEta +//│ deforest > call dlHelper⁰@result¹ @ fix² -> UnsafeEta +//│ deforest > call dlHelper⁰@result¹ @ fix⁰ -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ dlHelper² -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ fix².dlHelper¹ -> UnsafeEta +//│ deforest > call dlHelper⁰@result⁰ @ fix⁰.dlHelper¹ -> UnsafeEta +//│ deforest > call fix¹@result² @ fix² -> UnsafeEta +//│ deforest > call fix¹@result² @ fix⁰ -> UnsafeEta +//│ deforest > call fix¹@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -207,21 +207,21 @@ fun f(x) = if x is fun loop(l, n) = if n > 0 then loop(f(l), n - 1) else l id(loop(Nil, 2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ loop@loop.f@f -> UnsafeEta -//│ deforest > function f#0 @ loop@loop.f@f -> UnsafeEta -//│ deforest > function loop#0 @ loop@loop -> UnsafeEta -//│ deforest > function loop#0 @ loop@loop -> UnsafeEta -//│ deforest > call -@result @ loop@loop -> Pure -//│ deforest > call -@result @ loop@loop -> Pure -//│ deforest > call >@result @ loop@loop -> Pure -//│ deforest > call >@result @ loop@loop -> Pure -//│ deforest > call f@result @ loop@loop -> UnsafeEta -//│ deforest > call f@result @ loop@loop -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call loop@result @ -> UnsafeEta -//│ deforest > call loop@result @ loop@loop -> UnsafeEta -//│ deforest > call loop@result @ loop@loop -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ loop².f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ loop⁰.f¹ -> UnsafeEta +//│ deforest > function loop¹#0 @ loop² -> UnsafeEta +//│ deforest > function loop¹#0 @ loop⁰ -> UnsafeEta +//│ deforest > call -⁰@result² @ loop² -> Pure +//│ deforest > call -⁰@result² @ loop⁰ -> Pure +//│ deforest > call >⁰@result⁰ @ loop² -> Pure +//│ deforest > call >⁰@result⁰ @ loop⁰ -> Pure +//│ deforest > call f⁰@result¹ @ loop² -> UnsafeEta +//│ deforest > call f⁰@result¹ @ loop⁰ -> UnsafeEta +//│ deforest > call id@result⁴ @ -> UnsafeEta +//│ deforest > call loop¹@result³ @ loop² -> UnsafeEta +//│ deforest > call loop¹@result³ @ loop⁰ -> UnsafeEta +//│ deforest > call loop¹@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< diff --git a/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls b/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls index 5bcf9b02fa..8b84e65f2b 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/erasedTypes.mls @@ -48,7 +48,7 @@ fun selected(n: Int, k: Str) = if b is Box(x) then [x, k] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function selected#0 @ selected@selected -> UnsafeEta +//│ deforest > function selected⁰#0 @ selected¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Box¹(n⁰) -> @@ -85,7 +85,7 @@ fun withRest(n: Int, k: Str) = else 0 [r, k] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function withRest#0 @ withRest@withRest -> UnsafeEta +//│ deforest > function withRest⁰#0 @ withRest¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Box¹(n¹) -> @@ -122,7 +122,7 @@ fun noFields(n: Int, s: Str) = if p is Pair then 1 //│ deforest > >>> effect-analysis results >>> -//│ deforest > function noFields#0 @ noFields@noFields -> UnsafeEta +//│ deforest > function noFields⁰#0 @ noFields¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Pair¹(n², s⁰) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls index 9aaf98f34b..310cca1979 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/basic.mls @@ -25,12 +25,12 @@ fun c(x) = if x is X(a) then a c(p(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(x⁰) -> @@ -52,12 +52,12 @@ fun c(x) = if x is B then 2 c(p(true)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > function p#0 @ p@p -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> Pure +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> Pure +//│ deforest > function p⁰#0 @ p¹ -> Pure +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -79,15 +79,15 @@ fun g(y) = if y is Y(o) then o g(f(p())) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ -> UnsafeEta +//│ deforest > call g⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp⁰) -> @@ -113,12 +113,12 @@ fun c(x) = if x is X(Y(y)) then y c(p(true)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp¹) -> @@ -148,19 +148,19 @@ fun main(x) = c(p(2)) main(3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ main@main -> UnsafeEta -//│ deforest > function c#0 @ main@main -> UnsafeEta -//│ deforest > function main#0 @ main@main -> UnsafeEta -//│ deforest > function main#0 @ main@main -> UnsafeEta -//│ deforest > function p#0 @ main@main -> UnsafeEta -//│ deforest > function p#0 @ main@main -> UnsafeEta -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call c@result @ main@main -> UnsafeEta -//│ deforest > call c@result @ main@main -> UnsafeEta -//│ deforest > call main@result @ -> UnsafeEta -//│ deforest > call p@result @ main@main -> UnsafeEta -//│ deforest > call p@result @ main@main -> UnsafeEta +//│ deforest > function c⁰#0 @ main² -> UnsafeEta +//│ deforest > function c⁰#0 @ main⁰ -> UnsafeEta +//│ deforest > function main¹#0 @ main² -> UnsafeEta +//│ deforest > function main¹#0 @ main⁰ -> UnsafeEta +//│ deforest > function p⁰#0 @ main² -> UnsafeEta +//│ deforest > function p⁰#0 @ main⁰ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ main² -> Pure +//│ deforest > call +⁰@result⁰ @ main⁰ -> Pure +//│ deforest > call c⁰@result² @ main² -> UnsafeEta +//│ deforest > call c⁰@result² @ main⁰ -> UnsafeEta +//│ deforest > call main¹@result³ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ main² -> UnsafeEta +//│ deforest > call p⁰@result¹ @ main⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(tmp³) -> @@ -190,12 +190,12 @@ fun c(x) = if x is X(a) then a c(p(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > X⁰(x⁶) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls index a46f8b5f98..396b6a609e 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/eta-expansion/recursive.mls @@ -23,22 +23,22 @@ fun sum(ls, acc) = if ls is h :: t then sum(t, h + acc) sum(enum(5), 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call <@result @ enum@enum -> Pure -//│ deforest > call <@result @ enum@enum -> Pure -//│ deforest > call enum@result @ -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum² -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ sum² -> Pure +//│ deforest > call +⁰@result⁰ @ sum¹ -> Pure +//│ deforest > call -⁰@result³ @ enum² -> Pure +//│ deforest > call -⁰@result³ @ enum¹ -> Pure +//│ deforest > call <⁰@result² @ enum² -> Pure +//│ deforest > call <⁰@result² @ enum¹ -> Pure +//│ deforest > call enum⁰@result⁴ @ enum² -> UnsafeEta +//│ deforest > call enum⁰@result⁴ @ enum¹ -> UnsafeEta +//│ deforest > call enum⁰@result⁶ @ -> UnsafeEta +//│ deforest > call sum⁰@result¹ @ sum² -> UnsafeEta +//│ deforest > call sum⁰@result¹ @ sum¹ -> UnsafeEta +//│ deforest > call sum⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -124,27 +124,27 @@ fun len(ls) = if ls is h :: t then 1 + len(t) len(flatten(id((1 :: 2 :: Nil) :: (3 :: Nil) :: Nil))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta -//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta -//│ deforest > function len#0 @ len@len -> UnsafeEta -//│ deforest > function len#0 @ len@len -> UnsafeEta -//│ deforest > call +@result @ len@len -> Pure -//│ deforest > call +@result @ len@len -> Pure -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > call flatten@result @ -> UnsafeEta -//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta -//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call len@result @ -> UnsafeEta -//│ deforest > call len@result @ len@len -> UnsafeEta -//│ deforest > call len@result @ len@len -> UnsafeEta +//│ deforest > function append⁰#0 @ append² -> UnsafeEta +//│ deforest > function append⁰#0 @ flatten².append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ flatten⁰.append¹ -> UnsafeEta +//│ deforest > function flatten¹#0 @ flatten² -> UnsafeEta +//│ deforest > function flatten¹#0 @ flatten⁰ -> UnsafeEta +//│ deforest > function len⁰#0 @ len² -> UnsafeEta +//│ deforest > function len⁰#0 @ len¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ len² -> Pure +//│ deforest > call +⁰@result¹ @ len¹ -> Pure +//│ deforest > call append⁰@result³ @ append² -> UnsafeEta +//│ deforest > call append⁰@result³ @ flatten².append¹ -> UnsafeEta +//│ deforest > call append⁰@result³ @ flatten⁰.append¹ -> UnsafeEta +//│ deforest > call append⁰@result⁴ @ flatten² -> UnsafeEta +//│ deforest > call append⁰@result⁴ @ flatten⁰ -> UnsafeEta +//│ deforest > call flatten¹@result² @ flatten² -> UnsafeEta +//│ deforest > call flatten¹@result² @ flatten⁰ -> UnsafeEta +//│ deforest > call flatten¹@result⁶ @ -> UnsafeEta +//│ deforest > call id@result⁷ @ -> UnsafeEta +//│ deforest > call len⁰@result⁰ @ len² -> UnsafeEta +//│ deforest > call len⁰@result⁰ @ len¹ -> UnsafeEta +//│ deforest > call len⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -252,7 +252,7 @@ len(flatten(id((1 :: 2 :: Nil) :: (3 :: Nil) :: Nil))) :flowBasedOpt debugEta fun f(x) = f //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure +//│ deforest > function f⁰#0 @ f¹ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< diff --git a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls index f06ba4fcf5..4ecfbd7a1c 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls @@ -37,9 +37,9 @@ c(AA(3)) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(3) -> @@ -55,11 +55,11 @@ c(AA(7)) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c¹ -> Pure +//│ deforest > call c⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(7) -> @@ -87,17 +87,17 @@ c(AA(7)) //│ deforest > tmp⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function lambda#0 @ c@c -> UnsafeEta -//│ deforest > function lambda#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call cl@result @ c@c -> UnsafeEta -//│ deforest > call cl@result @ c@c -> UnsafeEta -//│ deforest > call cl@result @ c@c -> UnsafeEta -//│ deforest > call cl@result @ c@c -> UnsafeEta +//│ deforest > function c¹#0 @ c² -> UnsafeEta +//│ deforest > function c¹#0 @ c⁰ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ c² -> UnsafeEta +//│ deforest > function lambda⁰#0 @ c⁰ -> UnsafeEta +//│ deforest > call +⁰@result² @ c² -> Pure +//│ deforest > call +⁰@result² @ c⁰ -> Pure +//│ deforest > call cl⁰@result¹ @ c² -> UnsafeEta +//│ deforest > call cl⁰@result¹ @ c⁰ -> UnsafeEta +//│ deforest > call cl⁰@result⁰ @ c² -> UnsafeEta +//│ deforest > call cl⁰@result⁰ @ c⁰ -> UnsafeEta +//│ deforest > call c¹@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -113,17 +113,17 @@ affine_branched(AA(0), AA(1), (y) => if y is AA(x) then x + 2) //│ deforest > >>> non-affine syms >>> //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function affine_branched#0 @ affine_branched@affine_branched -> UnsafeEta -//│ deforest > function affine_branched#0 @ affine_branched@affine_branched -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call affine_branched@result @ -> UnsafeEta -//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta -//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta -//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta -//│ deforest > call cons_y@result @ affine_branched@affine_branched -> UnsafeEta +//│ deforest > function affine_branched⁰#0 @ affine_branched² -> UnsafeEta +//│ deforest > function affine_branched⁰#0 @ affine_branched¹ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ lambda² -> Pure +//│ deforest > call +⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call affine_branched⁰@result³ @ -> UnsafeEta +//│ deforest > call cons_y⁰@result² @ affine_branched² -> UnsafeEta +//│ deforest > call cons_y⁰@result² @ affine_branched¹ -> UnsafeEta +//│ deforest > call cons_y⁰@result¹ @ affine_branched² -> UnsafeEta +//│ deforest > call cons_y⁰@result¹ @ affine_branched¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(1) -> @@ -144,12 +144,12 @@ let p = AA(10) in //│ deforest > p¹ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c³ -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call c⁰@result² @ -> UnsafeEta +//│ deforest > call c⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -169,17 +169,17 @@ apply(c, AA(3)) //│ deforest > x_for_apply⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function apply#0 @ apply@apply -> UnsafeEta -//│ deforest > function apply#0 @ apply@apply -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ apply@apply -> Pure -//│ deforest > call +@result @ apply@apply -> Pure -//│ deforest > call apply@result @ -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta +//│ deforest > function apply⁰#0 @ apply² -> UnsafeEta +//│ deforest > function apply⁰#0 @ apply¹ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ apply² -> Pure +//│ deforest > call +⁰@result² @ apply¹ -> Pure +//│ deforest > call apply⁰@result³ @ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ apply² -> UnsafeEta +//│ deforest > call f⁰@result¹ @ apply¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ apply² -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ apply¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -195,13 +195,13 @@ c(AA(0), AA(3)) //│ deforest > x_for_c⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ c² -> Pure +//│ deforest > call +⁰@result¹ @ c¹ -> Pure +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c¹ -> Pure +//│ deforest > call c⁰@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(0) -> @@ -225,11 +225,11 @@ c(AA(1)) //│ deforest > y_for_c⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function _d#0 @ c@c -> UnsafeEta -//│ deforest > function _d#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function _d⁰#0 @ c² -> UnsafeEta +//│ deforest > function _d⁰#0 @ c⁰ -> UnsafeEta +//│ deforest > function c¹#0 @ c² -> UnsafeEta +//│ deforest > function c¹#0 @ c⁰ -> UnsafeEta +//│ deforest > call c¹@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -247,13 +247,13 @@ let p = AA(AA(AA(10))) in //│ deforest > tmp⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call c1@result @ -> UnsafeEta -//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1² -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1¹ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call c1⁰@result² @ -> UnsafeEta +//│ deforest > call c2⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -274,19 +274,19 @@ apply(c1, c2, Many(Once(10))) //│ deforest > tmp⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function apply#0 @ apply@apply -> UnsafeEta -//│ deforest > function apply#0 @ apply@apply -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > call +@result @ apply@apply -> Pure -//│ deforest > call +@result @ apply@apply -> Pure -//│ deforest > call apply@result @ -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta -//│ deforest > call g@result @ apply@apply -> UnsafeEta -//│ deforest > call g@result @ apply@apply -> UnsafeEta +//│ deforest > function apply⁰#0 @ apply² -> UnsafeEta +//│ deforest > function apply⁰#0 @ apply¹ -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1² -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1¹ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ apply² -> Pure +//│ deforest > call +⁰@result² @ apply¹ -> Pure +//│ deforest > call apply⁰@result³ @ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ apply² -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ apply¹ -> UnsafeEta +//│ deforest > call g⁰@result¹ @ apply² -> UnsafeEta +//│ deforest > call g⁰@result¹ @ apply¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -314,22 +314,22 @@ nest_consume(nest_pickB, nest_prod(10)) //│ deforest > x_for_nest_prod⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function nest_consume#0 @ nest_consume@nest_consume -> UnsafeEta -//│ deforest > function nest_consume#0 @ nest_consume@nest_consume -> UnsafeEta -//│ deforest > function nest_pickB#0 @ nest_pickB@nest_pickB -> UnsafeEta -//│ deforest > function nest_pickB#0 @ nest_pickB@nest_pickB -> UnsafeEta -//│ deforest > function nest_prod#0 @ nest_prod@nest_prod -> UnsafeEta -//│ deforest > function nest_prod#0 @ nest_prod@nest_prod -> UnsafeEta -//│ deforest > call +@result @ nest_consume@nest_consume -> Pure -//│ deforest > call +@result @ nest_consume@nest_consume -> Pure -//│ deforest > call +@result @ nest_pickB@nest_pickB -> Pure -//│ deforest > call +@result @ nest_pickB@nest_pickB -> Pure -//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta -//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta -//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta -//│ deforest > call f@result @ nest_consume@nest_consume -> UnsafeEta -//│ deforest > call nest_consume@result @ -> UnsafeEta -//│ deforest > call nest_prod@result @ -> UnsafeEta +//│ deforest > function nest_consume⁰#0 @ nest_consume² -> UnsafeEta +//│ deforest > function nest_consume⁰#0 @ nest_consume¹ -> UnsafeEta +//│ deforest > function nest_pickB⁰#0 @ nest_pickB² -> UnsafeEta +//│ deforest > function nest_pickB⁰#0 @ nest_pickB¹ -> UnsafeEta +//│ deforest > function nest_prod⁰#0 @ nest_prod² -> UnsafeEta +//│ deforest > function nest_prod⁰#0 @ nest_prod¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ nest_consume² -> Pure +//│ deforest > call +⁰@result³ @ nest_consume¹ -> Pure +//│ deforest > call +⁰@result⁰ @ nest_pickB² -> Pure +//│ deforest > call +⁰@result⁰ @ nest_pickB¹ -> Pure +//│ deforest > call f⁰@result² @ nest_consume² -> UnsafeEta +//│ deforest > call f⁰@result² @ nest_consume¹ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ nest_consume² -> UnsafeEta +//│ deforest > call f⁰@result¹ @ nest_consume¹ -> UnsafeEta +//│ deforest > call nest_consume⁰@result⁴ @ -> UnsafeEta +//│ deforest > call nest_prod⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> @@ -359,22 +359,22 @@ length(from(5, Nil)) //│ deforest > acc_for_from⁰ //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function from#0 @ from@from -> UnsafeEta -//│ deforest > function from#0 @ from@from -> UnsafeEta -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call -@result @ from@from -> Pure -//│ deforest > call -@result @ from@from -> Pure -//│ deforest > call equals@result @ from@from -> UnsafeEta -//│ deforest > call equals@result @ from@from -> UnsafeEta -//│ deforest > call from@result @ -> UnsafeEta -//│ deforest > call from@result @ from@from -> UnsafeEta -//│ deforest > call from@result @ from@from -> UnsafeEta -//│ deforest > call length@result @ -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > function from⁰#0 @ from² -> UnsafeEta +//│ deforest > function from⁰#0 @ from¹ -> UnsafeEta +//│ deforest > function length⁰#0 @ length² -> UnsafeEta +//│ deforest > function length⁰#0 @ length¹ -> UnsafeEta +//│ deforest > call +⁰@result⁴ @ length² -> Pure +//│ deforest > call +⁰@result⁴ @ length¹ -> Pure +//│ deforest > call -⁰@result¹ @ from² -> Pure +//│ deforest > call -⁰@result¹ @ from¹ -> Pure +//│ deforest > call equals@result⁰ @ from² -> UnsafeEta +//│ deforest > call equals@result⁰ @ from¹ -> UnsafeEta +//│ deforest > call from⁰@result² @ from² -> UnsafeEta +//│ deforest > call from⁰@result² @ from¹ -> UnsafeEta +//│ deforest > call from⁰@result⁶ @ -> UnsafeEta +//│ deforest > call length⁰@result³ @ length² -> UnsafeEta +//│ deforest > call length⁰@result³ @ length¹ -> UnsafeEta +//│ deforest > call length⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -394,19 +394,19 @@ length(append(id(1 :: Nil), 2 :: Nil)) //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call append@result @ -> UnsafeEta -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call length@result @ -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > function append⁰#0 @ append² -> UnsafeEta +//│ deforest > function append⁰#0 @ append¹ -> UnsafeEta +//│ deforest > function length⁰#0 @ length² -> UnsafeEta +//│ deforest > function length⁰#0 @ length¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ length² -> Pure +//│ deforest > call +⁰@result² @ length¹ -> Pure +//│ deforest > call append⁰@result⁰ @ append² -> UnsafeEta +//│ deforest > call append⁰@result⁰ @ append¹ -> UnsafeEta +//│ deforest > call append⁰@result⁴ @ -> UnsafeEta +//│ deforest > call id@result⁵ @ -> UnsafeEta +//│ deforest > call length⁰@result³ @ -> UnsafeEta +//│ deforest > call length⁰@result¹ @ length² -> UnsafeEta +//│ deforest > call length⁰@result¹ @ length¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h⁰, tmp¹) -> @@ -440,27 +440,27 @@ length(ping(id(1 :: 2 :: Nil), 3 :: 4 :: Nil)) //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > function ping#0 @ ping@ping -> UnsafeEta -//│ deforest > function ping#0 @ ping@ping -> UnsafeEta -//│ deforest > function ping#0 @ pong@pong -> UnsafeEta -//│ deforest > function pong#0 @ ping@ping -> UnsafeEta -//│ deforest > function pong#0 @ ping@ping -> UnsafeEta -//│ deforest > function pong#0 @ pong@pong -> UnsafeEta -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call length@result @ -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta -//│ deforest > call ping@result @ -> UnsafeEta -//│ deforest > call ping@result @ ping@ping -> UnsafeEta -//│ deforest > call ping@result @ ping@ping -> UnsafeEta -//│ deforest > call ping@result @ pong@pong -> UnsafeEta -//│ deforest > call pong@result @ ping@ping -> UnsafeEta -//│ deforest > call pong@result @ ping@ping -> UnsafeEta -//│ deforest > call pong@result @ pong@pong -> UnsafeEta +//│ deforest > function length⁰#0 @ length² -> UnsafeEta +//│ deforest > function length⁰#0 @ length¹ -> UnsafeEta +//│ deforest > function ping⁰#0 @ ping² -> UnsafeEta +//│ deforest > function ping⁰#0 @ ping¹ -> UnsafeEta +//│ deforest > function ping⁰#0 @ pong⁰ -> UnsafeEta +//│ deforest > function pong¹#0 @ ping² -> UnsafeEta +//│ deforest > function pong¹#0 @ ping¹ -> UnsafeEta +//│ deforest > function pong¹#0 @ pong⁰ -> UnsafeEta +//│ deforest > call +⁰@result³ @ length² -> Pure +//│ deforest > call +⁰@result³ @ length¹ -> Pure +//│ deforest > call id@result⁶ @ -> UnsafeEta +//│ deforest > call length⁰@result² @ length² -> UnsafeEta +//│ deforest > call length⁰@result² @ length¹ -> UnsafeEta +//│ deforest > call length⁰@result⁴ @ -> UnsafeEta +//│ deforest > call ping⁰@result¹ @ ping² -> UnsafeEta +//│ deforest > call ping⁰@result¹ @ ping¹ -> UnsafeEta +//│ deforest > call ping⁰@result¹ @ pong⁰ -> UnsafeEta +//│ deforest > call ping⁰@result⁵ @ -> UnsafeEta +//│ deforest > call pong¹@result⁰ @ ping² -> UnsafeEta +//│ deforest > call pong¹@result⁰ @ ping¹ -> UnsafeEta +//│ deforest > call pong¹@result⁰ @ pong⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(3, tmp²) -> @@ -493,19 +493,19 @@ sum(append(id(Nil), Nil), 0) //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call append@result @ -> UnsafeEta -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function append⁰#0 @ append² -> UnsafeEta +//│ deforest > function append⁰#0 @ append¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ sum² -> Pure +//│ deforest > call +⁰@result⁰ @ sum¹ -> Pure +//│ deforest > call append⁰@result² @ append² -> UnsafeEta +//│ deforest > call append⁰@result² @ append¹ -> UnsafeEta +//│ deforest > call append⁰@result⁴ @ -> UnsafeEta +//│ deforest > call id@result⁵ @ -> UnsafeEta +//│ deforest > call sum⁰@result³ @ -> UnsafeEta +//│ deforest > call sum⁰@result¹ @ sum² -> UnsafeEta +//│ deforest > call sum⁰@result¹ @ sum¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h², tmp³) -> @@ -549,27 +549,27 @@ length(flatten(id((1 :: Nil) :: Nil))) //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta -//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > function length#0 @ length@length -> UnsafeEta -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call +@result @ length@length -> Pure -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > call flatten@result @ -> UnsafeEta -//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta -//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call length@result @ -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta -//│ deforest > call length@result @ length@length -> UnsafeEta +//│ deforest > function append⁰#0 @ append² -> UnsafeEta +//│ deforest > function append⁰#0 @ flatten².append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ flatten⁰.append¹ -> UnsafeEta +//│ deforest > function flatten¹#0 @ flatten² -> UnsafeEta +//│ deforest > function flatten¹#0 @ flatten⁰ -> UnsafeEta +//│ deforest > function length⁰#0 @ length² -> UnsafeEta +//│ deforest > function length⁰#0 @ length¹ -> UnsafeEta +//│ deforest > call +⁰@result⁴ @ length² -> Pure +//│ deforest > call +⁰@result⁴ @ length¹ -> Pure +//│ deforest > call append⁰@result² @ flatten² -> UnsafeEta +//│ deforest > call append⁰@result² @ flatten⁰ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ append² -> UnsafeEta +//│ deforest > call append⁰@result¹ @ flatten².append¹ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ flatten⁰.append¹ -> UnsafeEta +//│ deforest > call flatten¹@result⁰ @ flatten² -> UnsafeEta +//│ deforest > call flatten¹@result⁰ @ flatten⁰ -> UnsafeEta +//│ deforest > call flatten¹@result⁶ @ -> UnsafeEta +//│ deforest > call id@result⁷ @ -> UnsafeEta +//│ deforest > call length⁰@result³ @ length² -> UnsafeEta +//│ deforest > call length⁰@result³ @ length¹ -> UnsafeEta +//│ deforest > call length⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(h³, tmp⁴) -> @@ -596,13 +596,13 @@ alias_then_patmat(Cons(12, 13)) //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function alias_then_patmat#0 @ alias_then_patmat@alias_then_patmat -> UnsafeEta -//│ deforest > function alias_then_patmat#0 @ alias_then_patmat@alias_then_patmat -> UnsafeEta -//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure -//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure -//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure -//│ deforest > call +@result @ alias_then_patmat@alias_then_patmat -> Pure -//│ deforest > call alias_then_patmat@result @ -> UnsafeEta +//│ deforest > function alias_then_patmat⁰#0 @ alias_then_patmat² -> UnsafeEta +//│ deforest > function alias_then_patmat⁰#0 @ alias_then_patmat¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ alias_then_patmat² -> Pure +//│ deforest > call +⁰@result¹ @ alias_then_patmat¹ -> Pure +//│ deforest > call +⁰@result⁰ @ alias_then_patmat² -> Pure +//│ deforest > call +⁰@result⁰ @ alias_then_patmat¹ -> Pure +//│ deforest > call alias_then_patmat⁰@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -621,17 +621,17 @@ foo of AA of () => 1 //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > call +@result @ foo@foo -> Pure -//│ deforest > call +@result @ foo@foo -> Pure -//│ deforest > call foo@result @ -> UnsafeEta -//│ deforest > call x@result @ foo@foo -> Pure -//│ deforest > call x@result @ foo@foo -> Pure -//│ deforest > call x@result @ foo@foo -> UnsafeEta -//│ deforest > call x@result @ foo@foo -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo² -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo¹ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > call +⁰@result² @ foo² -> Pure +//│ deforest > call +⁰@result² @ foo¹ -> Pure +//│ deforest > call foo⁰@result³ @ -> UnsafeEta +//│ deforest > call x@result¹ @ foo² -> Pure +//│ deforest > call x@result¹ @ foo¹ -> UnsafeEta +//│ deforest > call x@result⁰ @ foo² -> Pure +//│ deforest > call x@result⁰ @ foo¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(lambda⁰) -> @@ -659,17 +659,17 @@ foo of AA of () => 1 //│ deforest > >>> accumulator syms >>> //│ deforest > <<< accumulator syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > call +@result @ foo@foo -> Pure -//│ deforest > call +@result @ foo@foo -> Pure -//│ deforest > call f@result @ foo@foo -> Pure -//│ deforest > call f@result @ foo@foo -> Pure -//│ deforest > call f@result @ foo@foo -> UnsafeEta -//│ deforest > call f@result @ foo@foo -> UnsafeEta -//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo² -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo¹ -> UnsafeEta +//│ deforest > function lambda¹#0 @ lambda² -> Pure +//│ deforest > function lambda¹#0 @ lambda³ -> Pure +//│ deforest > call +⁰@result² @ foo² -> Pure +//│ deforest > call +⁰@result² @ foo¹ -> Pure +//│ deforest > call foo⁰@result³ @ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ foo² -> Pure +//│ deforest > call f⁰@result¹ @ foo¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ foo² -> Pure +//│ deforest > call f⁰@result⁰ @ foo¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(lambda¹) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/imperative.mls b/hkmc2/shared/src/test/mlscript/deforest/imperative.mls index ff0af9146d..c224abfd4f 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/imperative.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/imperative.mls @@ -22,8 +22,8 @@ fun foo(x) = A then 1 B then 2 //│ deforest > >>> effect-analysis results >>> -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > call print@result @ foo@foo -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo¹ -> UnsafeEta +//│ deforest > call print@result⁰ @ foo¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -35,9 +35,9 @@ fun foo(x) = if x is A do print(123) if x is B do print(456) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > call print@result @ foo@foo -> UnsafeEta -//│ deforest > call print@result @ foo@foo -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo¹ -> UnsafeEta +//│ deforest > call print@result¹ @ foo¹ -> UnsafeEta +//│ deforest > call print@result⁰ @ foo¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -55,19 +55,19 @@ fun bar(v) = if v is B then 2 foo(bar, 123) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function bar#0 @ bar@bar -> UnsafeEta -//│ deforest > function bar#0 @ bar@bar -> UnsafeEta -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > call ===@result @ foo@foo -> Pure -//│ deforest > call ===@result @ foo@foo -> Pure -//│ deforest > call >@result @ foo@foo -> Pure -//│ deforest > call >@result @ foo@foo -> Pure -//│ deforest > call foo@result @ -> UnsafeEta -//│ deforest > call k@result @ foo@foo -> UnsafeEta -//│ deforest > call k@result @ foo@foo -> UnsafeEta -//│ deforest > call k@result @ foo@foo -> UnsafeEta -//│ deforest > call k@result @ foo@foo -> UnsafeEta +//│ deforest > function bar⁰#0 @ bar² -> UnsafeEta +//│ deforest > function bar⁰#0 @ bar¹ -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo² -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo¹ -> UnsafeEta +//│ deforest > call ===⁰@result⁰ @ foo² -> Pure +//│ deforest > call ===⁰@result⁰ @ foo¹ -> Pure +//│ deforest > call >⁰@result² @ foo² -> Pure +//│ deforest > call >⁰@result² @ foo¹ -> Pure +//│ deforest > call foo⁰@result⁴ @ -> UnsafeEta +//│ deforest > call k⁰@result³ @ foo² -> UnsafeEta +//│ deforest > call k⁰@result³ @ foo¹ -> UnsafeEta +//│ deforest > call k⁰@result¹ @ foo² -> UnsafeEta +//│ deforest > call k⁰@result¹ @ foo¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls b/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls index 55cf18ae39..fe49aba37c 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/listComprehension.mls @@ -29,79 +29,79 @@ fun lscomp1(ls) = if ls is else Nil lscomp1(zip(enumFromTo(1, 3), enumFromTo(2, 4))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function zip#0 @ lscomp1@lscomp1.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ lscomp1@lscomp1.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ zip@zip -> UnsafeEta -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1 -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> Pure -//│ deforest > call enumFromTo@result @ -> UnsafeEta -//│ deforest > call enumFromTo@result @ -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ lscomp1@lscomp1.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call equals@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call equals@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp1@result @ -> UnsafeEta -//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call zip@result @ -> UnsafeEta -//│ deforest > call zip@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call zip@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call zip@result @ lscomp1@lscomp1.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ lscomp1@lscomp1.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ zip@zip -> UnsafeEta -//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo³ -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo⁴ -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo⁵ -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ lscomp1².enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ lscomp1².enumFromTo¹ -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ lscomp1⁰.enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ lscomp1⁰.enumFromTo¹ -> UnsafeEta +//│ deforest > function lscomp1¹#0 @ lscomp1² -> UnsafeEta +//│ deforest > function lscomp1¹#0 @ lscomp1⁰ -> UnsafeEta +//│ deforest > function lscomp2⁰#0 @ lscomp1² -> UnsafeEta +//│ deforest > function lscomp2⁰#0 @ lscomp1⁰ -> UnsafeEta +//│ deforest > function zip⁰#0 @ lscomp1².zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ lscomp1⁰.zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ zip² -> UnsafeEta +//│ deforest > function zip⁰#0 @ zip³ -> UnsafeEta +//│ deforest > call +⁰@result¹¹ @ lscomp1² -> Pure +//│ deforest > call +⁰@result¹¹ @ lscomp1⁰ -> Pure +//│ deforest > call +⁰@result⁵ @ lscomp1² -> Pure +//│ deforest > call +⁰@result⁵ @ lscomp1⁰ -> Pure +//│ deforest > call +⁰@result⁷ @ enumFromTo³ -> Pure +//│ deforest > call +⁰@result⁷ @ enumFromTo⁴ -> Pure +//│ deforest > call +⁰@result⁷ @ enumFromTo⁵ -> Pure +//│ deforest > call +⁰@result⁷ @ lscomp1².enumFromTo² -> Pure +//│ deforest > call +⁰@result⁷ @ lscomp1².enumFromTo¹ -> Pure +//│ deforest > call +⁰@result⁷ @ lscomp1⁰.enumFromTo² -> Pure +//│ deforest > call +⁰@result⁷ @ lscomp1⁰.enumFromTo¹ -> Pure +//│ deforest > call +⁰@result⁹ @ enumFromTo³ -> Pure +//│ deforest > call +⁰@result⁹ @ enumFromTo⁴ -> Pure +//│ deforest > call +⁰@result⁹ @ enumFromTo⁵ -> Pure +//│ deforest > call +⁰@result⁹ @ lscomp1².enumFromTo² -> Pure +//│ deforest > call +⁰@result⁹ @ lscomp1².enumFromTo¹ -> Pure +//│ deforest > call +⁰@result⁹ @ lscomp1⁰.enumFromTo² -> Pure +//│ deforest > call +⁰@result⁹ @ lscomp1⁰.enumFromTo¹ -> Pure +//│ deforest > call <⁰@result⁸ @ enumFromTo³ -> Pure +//│ deforest > call <⁰@result⁸ @ enumFromTo⁴ -> Pure +//│ deforest > call <⁰@result⁸ @ enumFromTo⁵ -> Pure +//│ deforest > call <⁰@result⁸ @ lscomp1².enumFromTo² -> Pure +//│ deforest > call <⁰@result⁸ @ lscomp1².enumFromTo¹ -> Pure +//│ deforest > call <⁰@result⁸ @ lscomp1⁰.enumFromTo² -> Pure +//│ deforest > call <⁰@result⁸ @ lscomp1⁰.enumFromTo¹ -> Pure +//│ deforest > call enumFromTo⁰@result¹² @ lscomp1² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result¹² @ lscomp1⁰ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result¹⁰ @ lscomp1² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result¹⁰ @ lscomp1⁰ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result¹⁸ @ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result¹⁹ @ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ enumFromTo³ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ enumFromTo⁴ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ enumFromTo⁵ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ lscomp1².enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ lscomp1².enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ lscomp1⁰.enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ lscomp1⁰.enumFromTo¹ -> UnsafeEta +//│ deforest > call equals@result⁰ @ lscomp1² -> UnsafeEta +//│ deforest > call equals@result⁰ @ lscomp1⁰ -> UnsafeEta +//│ deforest > call lscomp1¹@result³ @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp1¹@result³ @ lscomp1⁰ -> UnsafeEta +//│ deforest > call lscomp1¹@result¹⁶ @ -> UnsafeEta +//│ deforest > call lscomp1¹@result⁴ @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp1¹@result⁴ @ lscomp1⁰ -> UnsafeEta +//│ deforest > call lscomp2⁰@result² @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp2⁰@result² @ lscomp1⁰ -> UnsafeEta +//│ deforest > call lscomp2⁰@result¹ @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp2⁰@result¹ @ lscomp1⁰ -> UnsafeEta +//│ deforest > call lscomp2⁰@result¹⁵ @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp2⁰@result¹⁵ @ lscomp1⁰ -> UnsafeEta +//│ deforest > call zip⁰@result¹³ @ lscomp1².zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result¹³ @ lscomp1⁰.zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result¹³ @ zip² -> UnsafeEta +//│ deforest > call zip⁰@result¹³ @ zip³ -> UnsafeEta +//│ deforest > call zip⁰@result¹⁴ @ lscomp1² -> UnsafeEta +//│ deforest > call zip⁰@result¹⁴ @ lscomp1⁰ -> UnsafeEta +//│ deforest > call zip⁰@result¹⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -182,39 +182,39 @@ fun f1(a1) = if a1 is else Nil concatMap(f1, Pair(5, 10) :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > function append#0 @ concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > function append#0 @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > function append#0 @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > function concatMap#0 @ concatMap@concatMap -> UnsafeEta -//│ deforest > function concatMap#0 @ concatMap@concatMap -> UnsafeEta -//│ deforest > function concatMap#0 @ f1@f1.concatMap@concatMap -> UnsafeEta -//│ deforest > function concatMap#0 @ f1@f1.concatMap@concatMap -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f1@f1 -> UnsafeEta -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ concatMap@concatMap -> UnsafeEta -//│ deforest > call append@result @ concatMap@concatMap -> UnsafeEta -//│ deforest > call append@result @ concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > call append@result @ concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > call append@result @ f1@f1.concatMap@concatMap -> UnsafeEta -//│ deforest > call append@result @ f1@f1.concatMap@concatMap -> UnsafeEta -//│ deforest > call append@result @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > call append@result @ f1@f1.concatMap@concatMap.append@append -> UnsafeEta -//│ deforest > call concatMap@result @ -> UnsafeEta -//│ deforest > call concatMap@result @ concatMap@concatMap -> UnsafeEta -//│ deforest > call concatMap@result @ concatMap@concatMap -> UnsafeEta -//│ deforest > call concatMap@result @ f1@f1 -> UnsafeEta -//│ deforest > call concatMap@result @ f1@f1 -> UnsafeEta -//│ deforest > call concatMap@result @ f1@f1.concatMap@concatMap -> UnsafeEta -//│ deforest > call concatMap@result @ f1@f1.concatMap@concatMap -> UnsafeEta -//│ deforest > call f@result @ concatMap@concatMap -> UnsafeEta -//│ deforest > call f@result @ concatMap@concatMap -> UnsafeEta -//│ deforest > call f@result @ f1@f1.concatMap@concatMap -> UnsafeEta -//│ deforest > call f@result @ f1@f1.concatMap@concatMap -> UnsafeEta +//│ deforest > function append⁰#0 @ append² -> UnsafeEta +//│ deforest > function append⁰#0 @ concatMap².append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ concatMap³.append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ f1².concatMap¹.append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ f1⁰.concatMap¹.append¹ -> UnsafeEta +//│ deforest > function concatMap⁰#0 @ concatMap² -> UnsafeEta +//│ deforest > function concatMap⁰#0 @ concatMap³ -> UnsafeEta +//│ deforest > function concatMap⁰#0 @ f1².concatMap¹ -> UnsafeEta +//│ deforest > function concatMap⁰#0 @ f1⁰.concatMap¹ -> UnsafeEta +//│ deforest > function f1¹#0 @ f1² -> UnsafeEta +//│ deforest > function f1¹#0 @ f1⁰ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f1⁰ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ append² -> UnsafeEta +//│ deforest > call append⁰@result¹ @ concatMap².append¹ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ concatMap³.append¹ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ f1².concatMap¹.append¹ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ f1⁰.concatMap¹.append¹ -> UnsafeEta +//│ deforest > call append⁰@result⁰ @ concatMap² -> UnsafeEta +//│ deforest > call append⁰@result⁰ @ concatMap³ -> UnsafeEta +//│ deforest > call append⁰@result⁰ @ f1².concatMap¹ -> UnsafeEta +//│ deforest > call append⁰@result⁰ @ f1⁰.concatMap¹ -> UnsafeEta +//│ deforest > call concatMap⁰@result² @ concatMap² -> UnsafeEta +//│ deforest > call concatMap⁰@result² @ concatMap³ -> UnsafeEta +//│ deforest > call concatMap⁰@result² @ f1².concatMap¹ -> UnsafeEta +//│ deforest > call concatMap⁰@result² @ f1⁰.concatMap¹ -> UnsafeEta +//│ deforest > call concatMap⁰@result⁴ @ f1² -> UnsafeEta +//│ deforest > call concatMap⁰@result⁴ @ f1⁰ -> UnsafeEta +//│ deforest > call concatMap⁰@result⁵ @ -> UnsafeEta +//│ deforest > call f⁰@result³ @ concatMap² -> UnsafeEta +//│ deforest > call f⁰@result³ @ concatMap³ -> UnsafeEta +//│ deforest > call f⁰@result³ @ f1².concatMap¹ -> UnsafeEta +//│ deforest > call f⁰@result³ @ f1⁰.concatMap¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(tmp³, Nil⁰) -> @@ -317,22 +317,22 @@ fun lscomp2(ls2, h1, t1) = if ls2 is Nil then lscomp1(t1, ls2) lscomp1(1 :: 2 :: Nil, 3 :: 4 :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function lscomp1#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function lscomp1#0 @ lscomp2@lscomp2 -> UnsafeEta -//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function lscomp2#0 @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > function lscomp2#0 @ lscomp2@lscomp2 -> UnsafeEta -//│ deforest > call lscomp1@result @ -> UnsafeEta -//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp1@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp1@result @ lscomp2@lscomp2 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp1@lscomp1 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp2@lscomp2 -> UnsafeEta -//│ deforest > call lscomp2@result @ lscomp2@lscomp2 -> UnsafeEta +//│ deforest > function lscomp1⁰#0 @ lscomp1² -> UnsafeEta +//│ deforest > function lscomp1⁰#0 @ lscomp1¹ -> UnsafeEta +//│ deforest > function lscomp1⁰#0 @ lscomp2⁰ -> UnsafeEta +//│ deforest > function lscomp2¹#0 @ lscomp1² -> UnsafeEta +//│ deforest > function lscomp2¹#0 @ lscomp1¹ -> UnsafeEta +//│ deforest > function lscomp2¹#0 @ lscomp2⁰ -> UnsafeEta +//│ deforest > call lscomp1⁰@result² @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp1⁰@result² @ lscomp1¹ -> UnsafeEta +//│ deforest > call lscomp1⁰@result² @ lscomp2⁰ -> UnsafeEta +//│ deforest > call lscomp1⁰@result³ @ -> UnsafeEta +//│ deforest > call lscomp2¹@result¹ @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp2¹@result¹ @ lscomp1¹ -> UnsafeEta +//│ deforest > call lscomp2¹@result¹ @ lscomp2⁰ -> UnsafeEta +//│ deforest > call lscomp2¹@result⁰ @ lscomp1² -> UnsafeEta +//│ deforest > call lscomp2¹@result⁰ @ lscomp1¹ -> UnsafeEta +//│ deforest > call lscomp2¹@result⁰ @ lscomp2⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp¹¹) -> @@ -357,13 +357,13 @@ if A is A then lscomp(1 :: 2 :: 3 :: Nil) B then Nil //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lscomp#0 @ lscomp@lscomp -> UnsafeEta -//│ deforest > function lscomp#0 @ lscomp@lscomp -> UnsafeEta -//│ deforest > call +@result @ lscomp@lscomp -> Pure -//│ deforest > call +@result @ lscomp@lscomp -> Pure -//│ deforest > call lscomp@result @ -> UnsafeEta -//│ deforest > call lscomp@result @ lscomp@lscomp -> UnsafeEta -//│ deforest > call lscomp@result @ lscomp@lscomp -> UnsafeEta +//│ deforest > function lscomp⁰#0 @ lscomp² -> UnsafeEta +//│ deforest > function lscomp⁰#0 @ lscomp¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ lscomp² -> Pure +//│ deforest > call +⁰@result⁰ @ lscomp¹ -> Pure +//│ deforest > call lscomp⁰@result² @ -> UnsafeEta +//│ deforest > call lscomp⁰@result¹ @ lscomp² -> UnsafeEta +//│ deforest > call lscomp⁰@result¹ @ lscomp¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp¹²) -> @@ -398,21 +398,21 @@ fun h() = lscomp1(1 :: 2 :: 3 :: Nil) h() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function h#0 @ h@h -> UnsafeEta -//│ deforest > function h#0 @ h@h -> UnsafeEta -//│ deforest > function lscomp1#0 @ h@h -> UnsafeEta -//│ deforest > function lscomp1#0 @ h@h -> UnsafeEta -//│ deforest > function lscomp2#0 @ h@h -> UnsafeEta -//│ deforest > function lscomp2#0 @ h@h -> UnsafeEta -//│ deforest > call h@result @ -> UnsafeEta -//│ deforest > call lscomp1@result @ h@h -> UnsafeEta -//│ deforest > call lscomp1@result @ h@h -> UnsafeEta -//│ deforest > call lscomp1@result @ h@h -> UnsafeEta -//│ deforest > call lscomp1@result @ h@h -> UnsafeEta -//│ deforest > call lscomp2@result @ h@h -> UnsafeEta -//│ deforest > call lscomp2@result @ h@h -> UnsafeEta -//│ deforest > call lscomp2@result @ h@h -> UnsafeEta -//│ deforest > call lscomp2@result @ h@h -> UnsafeEta +//│ deforest > function h³#0 @ h² -> UnsafeEta +//│ deforest > function h³#0 @ h⁴ -> UnsafeEta +//│ deforest > function lscomp1⁰#0 @ h² -> UnsafeEta +//│ deforest > function lscomp1⁰#0 @ h⁴ -> UnsafeEta +//│ deforest > function lscomp2⁰#0 @ h² -> UnsafeEta +//│ deforest > function lscomp2⁰#0 @ h⁴ -> UnsafeEta +//│ deforest > call h³@result⁴ @ -> UnsafeEta +//│ deforest > call lscomp1⁰@result³ @ h² -> UnsafeEta +//│ deforest > call lscomp1⁰@result³ @ h⁴ -> UnsafeEta +//│ deforest > call lscomp1⁰@result⁰ @ h² -> UnsafeEta +//│ deforest > call lscomp1⁰@result⁰ @ h⁴ -> UnsafeEta +//│ deforest > call lscomp2⁰@result² @ h² -> UnsafeEta +//│ deforest > call lscomp2⁰@result² @ h⁴ -> UnsafeEta +//│ deforest > call lscomp2⁰@result¹ @ h² -> UnsafeEta +//│ deforest > call lscomp2⁰@result¹ @ h⁴ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp¹⁴) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/module.mls b/hkmc2/shared/src/test/mlscript/deforest/module.mls index 90906a3667..bf73220ff9 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/module.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/module.mls @@ -14,17 +14,17 @@ module M with XX(YY(y)) then h() M.f(M.p()) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function h#0 @ f@f.h@h -> Pure -//│ deforest > function h#0 @ f@f.h@h -> Pure -//│ deforest > function h#0 @ h@h -> Pure -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f¹#0 @ f² -> UnsafeEta +//│ deforest > function f¹#0 @ f⁰ -> UnsafeEta +//│ deforest > function h⁰#0 @ f².h¹ -> Pure +//│ deforest > function h⁰#0 @ f⁰.h¹ -> Pure +//│ deforest > function h⁰#0 @ h² -> Pure +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call f@result¹ @ -> UnsafeEta +//│ deforest > call h@result⁰ @ f² -> Pure +//│ deforest > call h@result⁰ @ f⁰ -> Pure +//│ deforest > call p@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > M⁰.this.XX⁰(tmp⁰) -> @@ -54,44 +54,44 @@ module DeforestList with val res = DeforestList.sum(DeforestList.enum(100)) DeforestList.res + DeforestList.main() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta -//│ deforest > function main#0 @ main@main -> UnsafeEta -//│ deforest > function main#0 @ main@main -> UnsafeEta -//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ main@main.sum@sum -> Pure -//│ deforest > call +@result @ main@main.sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ main@main.enum@enum -> Pure -//│ deforest > call -@result @ main@main.enum@enum -> Pure -//│ deforest > call >@result @ enum@enum -> Pure -//│ deforest > call >@result @ enum@enum -> Pure -//│ deforest > call >@result @ main@main.enum@enum -> Pure -//│ deforest > call >@result @ main@main.enum@enum -> Pure -//│ deforest > call enum@result @ -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ main@main -> UnsafeEta -//│ deforest > call enum@result @ main@main -> UnsafeEta -//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta -//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta -//│ deforest > call main@result @ -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ main@main -> UnsafeEta -//│ deforest > call sum@result @ main@main -> UnsafeEta -//│ deforest > call sum@result @ main@main.sum@sum -> UnsafeEta -//│ deforest > call sum@result @ main@main.sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum² -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum³ -> UnsafeEta +//│ deforest > function enum⁰#0 @ main².enum¹ -> UnsafeEta +//│ deforest > function enum⁰#0 @ main⁰.enum¹ -> UnsafeEta +//│ deforest > function main¹#0 @ main² -> UnsafeEta +//│ deforest > function main¹#0 @ main⁰ -> UnsafeEta +//│ deforest > function sum⁰#0 @ main².sum¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ main⁰.sum¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum³ -> UnsafeEta +//│ deforest > call +⁰@result⁴ @ main².sum¹ -> Pure +//│ deforest > call +⁰@result⁴ @ main⁰.sum¹ -> Pure +//│ deforest > call +⁰@result⁴ @ sum² -> Pure +//│ deforest > call +⁰@result⁴ @ sum³ -> Pure +//│ deforest > call +⁰@result⁷ @ -> Pure +//│ deforest > call -⁰@result¹ @ enum² -> Pure +//│ deforest > call -⁰@result¹ @ enum³ -> Pure +//│ deforest > call -⁰@result¹ @ main².enum¹ -> Pure +//│ deforest > call -⁰@result¹ @ main⁰.enum¹ -> Pure +//│ deforest > call >⁰@result² @ enum² -> Pure +//│ deforest > call >⁰@result² @ enum³ -> Pure +//│ deforest > call >⁰@result² @ main².enum¹ -> Pure +//│ deforest > call >⁰@result² @ main⁰.enum¹ -> Pure +//│ deforest > call enum@result³ @ main² -> UnsafeEta +//│ deforest > call enum@result³ @ main⁰ -> UnsafeEta +//│ deforest > call enum@result¹⁰ @ -> UnsafeEta +//│ deforest > call enum@result⁰ @ enum² -> UnsafeEta +//│ deforest > call enum@result⁰ @ enum³ -> UnsafeEta +//│ deforest > call enum@result⁰ @ main².enum¹ -> UnsafeEta +//│ deforest > call enum@result⁰ @ main⁰.enum¹ -> UnsafeEta +//│ deforest > call main@result⁸ @ -> UnsafeEta +//│ deforest > call sum@result⁵ @ main².sum¹ -> UnsafeEta +//│ deforest > call sum@result⁵ @ main⁰.sum¹ -> UnsafeEta +//│ deforest > call sum@result⁵ @ sum² -> UnsafeEta +//│ deforest > call sum@result⁵ @ sum³ -> UnsafeEta +//│ deforest > call sum@result⁶ @ main² -> UnsafeEta +//│ deforest > call sum@result⁶ @ main⁰ -> UnsafeEta +//│ deforest > call sum@result⁹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > DeforestList⁰.this.Nil⁰ -> @@ -134,52 +134,52 @@ module DeforestList with val res = DeforestList.sum(DeforestList.enum(100)) DeforestList.res + DeforestList.main() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ main@main.enum@enum -> UnsafeEta -//│ deforest > function helper#0 @ main@main.sum@sum -> UnsafeEta -//│ deforest > function helper#0 @ main@main.sum@sum -> UnsafeEta -//│ deforest > function helper#0 @ sum@sum -> UnsafeEta -//│ deforest > function helper#0 @ sum@sum -> UnsafeEta -//│ deforest > function main#0 @ main@main -> UnsafeEta -//│ deforest > function main#0 @ main@main -> UnsafeEta -//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ main@main.sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ main@main.sum@sum -> Pure -//│ deforest > call +@result @ main@main.sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ main@main.enum@enum -> Pure -//│ deforest > call -@result @ main@main.enum@enum -> Pure -//│ deforest > call >@result @ enum@enum -> Pure -//│ deforest > call >@result @ enum@enum -> Pure -//│ deforest > call >@result @ main@main.enum@enum -> Pure -//│ deforest > call >@result @ main@main.enum@enum -> Pure -//│ deforest > call enum@result @ -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ main@main -> UnsafeEta -//│ deforest > call enum@result @ main@main -> UnsafeEta -//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta -//│ deforest > call enum@result @ main@main.enum@enum -> UnsafeEta -//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta -//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta -//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta -//│ deforest > call helper@result @ main@main.sum@sum -> UnsafeEta -//│ deforest > call helper@result @ sum@sum -> UnsafeEta -//│ deforest > call helper@result @ sum@sum -> UnsafeEta -//│ deforest > call helper@result @ sum@sum -> UnsafeEta -//│ deforest > call helper@result @ sum@sum -> UnsafeEta -//│ deforest > call main@result @ -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ main@main -> UnsafeEta -//│ deforest > call sum@result @ main@main -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum² -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum³ -> UnsafeEta +//│ deforest > function enum⁰#0 @ main².enum¹ -> UnsafeEta +//│ deforest > function enum⁰#0 @ main⁰.enum¹ -> UnsafeEta +//│ deforest > function helper⁰#0 @ main².sum¹ -> UnsafeEta +//│ deforest > function helper⁰#0 @ main⁰.sum¹ -> UnsafeEta +//│ deforest > function helper⁰#0 @ sum² -> UnsafeEta +//│ deforest > function helper⁰#0 @ sum³ -> UnsafeEta +//│ deforest > function main¹#0 @ main² -> UnsafeEta +//│ deforest > function main¹#0 @ main⁰ -> UnsafeEta +//│ deforest > function sum⁰#0 @ main².sum¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ main⁰.sum¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum³ -> UnsafeEta +//│ deforest > call +⁰@result⁶ @ main².sum¹ -> Pure +//│ deforest > call +⁰@result⁶ @ main⁰.sum¹ -> Pure +//│ deforest > call +⁰@result⁶ @ sum² -> Pure +//│ deforest > call +⁰@result⁶ @ sum³ -> Pure +//│ deforest > call +⁰@result⁸ @ -> Pure +//│ deforest > call -⁰@result¹ @ enum² -> Pure +//│ deforest > call -⁰@result¹ @ enum³ -> Pure +//│ deforest > call -⁰@result¹ @ main².enum¹ -> Pure +//│ deforest > call -⁰@result¹ @ main⁰.enum¹ -> Pure +//│ deforest > call >⁰@result² @ enum² -> Pure +//│ deforest > call >⁰@result² @ enum³ -> Pure +//│ deforest > call >⁰@result² @ main².enum¹ -> Pure +//│ deforest > call >⁰@result² @ main⁰.enum¹ -> Pure +//│ deforest > call enum@result³ @ main² -> UnsafeEta +//│ deforest > call enum@result³ @ main⁰ -> UnsafeEta +//│ deforest > call enum@result¹¹ @ -> UnsafeEta +//│ deforest > call enum@result⁰ @ enum² -> UnsafeEta +//│ deforest > call enum@result⁰ @ enum³ -> UnsafeEta +//│ deforest > call enum@result⁰ @ main².enum¹ -> UnsafeEta +//│ deforest > call enum@result⁰ @ main⁰.enum¹ -> UnsafeEta +//│ deforest > call helper⁰@result⁴ @ main².sum¹ -> UnsafeEta +//│ deforest > call helper⁰@result⁴ @ main⁰.sum¹ -> UnsafeEta +//│ deforest > call helper⁰@result⁴ @ sum² -> UnsafeEta +//│ deforest > call helper⁰@result⁴ @ sum³ -> UnsafeEta +//│ deforest > call helper⁰@result⁵ @ main².sum¹ -> UnsafeEta +//│ deforest > call helper⁰@result⁵ @ main⁰.sum¹ -> UnsafeEta +//│ deforest > call helper⁰@result⁵ @ sum² -> UnsafeEta +//│ deforest > call helper⁰@result⁵ @ sum³ -> UnsafeEta +//│ deforest > call main@result⁹ @ -> UnsafeEta +//│ deforest > call sum@result¹⁰ @ -> UnsafeEta +//│ deforest > call sum@result⁷ @ main² -> UnsafeEta +//│ deforest > call sum@result⁷ @ main⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > DeforestList¹.this.Nil¹ -> @@ -215,11 +215,11 @@ module MMM with if A is A then y MMM.f() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call f@result¹ @ -> UnsafeEta +//│ deforest > call f@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > MMM⁰.this.A⁰ -> @@ -246,9 +246,9 @@ module M with Y then x M.f(M.X) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call f@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > M¹.X⁰ -> @@ -278,36 +278,36 @@ module M with C [M.f(3), M.g(true)] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ g@g -> UnsafeEta -//│ deforest > function f#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ g@g -> Pure -//│ deforest > call -@result @ g@g -> Pure -//│ deforest > call <@result @ f@f -> Pure -//│ deforest > call <@result @ f@f -> Pure -//│ deforest > call <@result @ g@g -> Pure -//│ deforest > call <@result @ g@g -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ g@g -> UnsafeEta -//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ g² -> UnsafeEta +//│ deforest > function f⁰#0 @ g⁰ -> UnsafeEta +//│ deforest > function g¹#0 @ f² -> UnsafeEta +//│ deforest > function g¹#0 @ f¹ -> UnsafeEta +//│ deforest > function g¹#0 @ g² -> UnsafeEta +//│ deforest > function g¹#0 @ g⁰ -> UnsafeEta +//│ deforest > call -⁰@result² @ f² -> Pure +//│ deforest > call -⁰@result² @ f¹ -> Pure +//│ deforest > call -⁰@result² @ g² -> Pure +//│ deforest > call -⁰@result² @ g⁰ -> Pure +//│ deforest > call <⁰@result¹ @ f² -> Pure +//│ deforest > call <⁰@result¹ @ f¹ -> Pure +//│ deforest > call <⁰@result¹ @ g² -> Pure +//│ deforest > call <⁰@result¹ @ g⁰ -> Pure +//│ deforest > call f@result³ @ f² -> UnsafeEta +//│ deforest > call f@result³ @ f¹ -> UnsafeEta +//│ deforest > call f@result³ @ g² -> UnsafeEta +//│ deforest > call f@result³ @ g⁰ -> UnsafeEta +//│ deforest > call f@result⁴ @ f² -> UnsafeEta +//│ deforest > call f@result⁴ @ f¹ -> UnsafeEta +//│ deforest > call f@result⁴ @ g² -> UnsafeEta +//│ deforest > call f@result⁴ @ g⁰ -> UnsafeEta +//│ deforest > call f@result⁶ @ -> UnsafeEta +//│ deforest > call g@result⁰ @ f² -> UnsafeEta +//│ deforest > call g@result⁰ @ f¹ -> UnsafeEta +//│ deforest > call g@result⁰ @ g² -> UnsafeEta +//│ deforest > call g@result⁰ @ g⁰ -> UnsafeEta +//│ deforest > call g@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰(0) -> @@ -349,14 +349,14 @@ private fun g(x, module I: O.I) = if x is I.C(y) then y + 2 g(f(O.I), O.I) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ g² -> Pure +//│ deforest > call +⁰@result⁰ @ g¹ -> Pure +//│ deforest > call f⁰@result² @ -> UnsafeEta +//│ deforest > call g⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > I⁰.C¹(3) -> @@ -373,14 +373,14 @@ private fun g(x, module O: O) = if x is O.I.C(y) then y + 2 g(f(O), O) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ g² -> Pure +//│ deforest > call +⁰@result⁰ @ g¹ -> Pure +//│ deforest > call f⁰@result² @ -> UnsafeEta +//│ deforest > call g⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > O⁰.I¹.C¹(3) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls b/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls index 739d8636ec..957a195275 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/multiArgLists.mls @@ -13,15 +13,15 @@ fun test(a)(b) = if a is Pair(x, y) then x + y + b test(Pair(1, 2))(3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#1 @ test@test -> UnsafeEta -//│ deforest > function test#1 @ test@test -> UnsafeEta -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> Pure +//│ deforest > function test⁰#0 @ test¹ -> Pure +//│ deforest > function test⁰#1 @ test² -> UnsafeEta +//│ deforest > function test⁰#1 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ test² -> Pure +//│ deforest > call +⁰@result¹ @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call test⁰@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Pair⁰(1, 2) -> @@ -42,13 +42,13 @@ fun unbox(b)(offset) = if b is Box(v) then v + offset unbox(Box(10))(5) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function unbox#0 @ unbox@unbox -> Pure -//│ deforest > function unbox#0 @ unbox@unbox -> Pure -//│ deforest > function unbox#1 @ unbox@unbox -> UnsafeEta -//│ deforest > function unbox#1 @ unbox@unbox -> UnsafeEta -//│ deforest > call +@result @ unbox@unbox -> Pure -//│ deforest > call +@result @ unbox@unbox -> Pure -//│ deforest > call unbox@result @ -> UnsafeEta +//│ deforest > function unbox⁰#0 @ unbox² -> Pure +//│ deforest > function unbox⁰#0 @ unbox¹ -> Pure +//│ deforest > function unbox⁰#1 @ unbox² -> UnsafeEta +//│ deforest > function unbox⁰#1 @ unbox¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ unbox² -> Pure +//│ deforest > call +⁰@result⁰ @ unbox¹ -> Pure +//│ deforest > call unbox⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Box⁰(10) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls b/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls index 7ce5a0106f..a745f194a3 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/nestedMatch.mls @@ -41,27 +41,27 @@ fun g(x) = if x is let a = AA(AA(3)) f(a, 2) + g(a) + f(BB(3), 2) + f(AA(AA(4)), 5) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ f⁴ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ f² -> Pure +//│ deforest > call +⁰@result¹ @ f³ -> Pure +//│ deforest > call +⁰@result¹ @ f¹ -> Pure +//│ deforest > call +⁰@result¹ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call +⁰@result⁶ @ -> Pure +//│ deforest > call f⁰@result³ @ -> UnsafeEta +//│ deforest > call f⁰@result⁵ @ -> UnsafeEta +//│ deforest > call f⁰@result⁸ @ -> UnsafeEta +//│ deforest > call g⁰@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> @@ -88,18 +88,18 @@ fun f(x, y) = n + 2 + y f(AA(AA(3)), 9) + f(AA(AA(4)), 10) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ f² -> Pure +//│ deforest > call +⁰@result¹ @ f³ -> Pure +//│ deforest > call +⁰@result¹ @ f¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call f⁰@result³ @ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp¹) -> @@ -128,11 +128,11 @@ fun f(x) = n + 2 f(AA(AA(3))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call f⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp³) -> @@ -153,15 +153,15 @@ fun f(x) = t + 3 f(AA(AA(A))) + f(AA(AA(A))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call f⁰@result² @ -> UnsafeEta +//│ deforest > call f⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁴) -> @@ -186,9 +186,9 @@ fun c2(x) = if x is AA(AA(a)) then a c2(AA(AA(0))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > call c2@result @ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2¹ -> UnsafeEta +//│ deforest > call c2⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁶) -> @@ -207,9 +207,9 @@ fun f(a) = if a is AA(BB(B)) then 3 f(AA(BB(B))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁷) -> @@ -234,21 +234,21 @@ fun test(x, y, z, i) = if x is m + n test(AA(1), AA(2), BB(3), 4) + test(AA(1), AA(2), BB(3), 4) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ test² -> Pure +//│ deforest > call +⁰@result² @ test³ -> Pure +//│ deforest > call +⁰@result² @ test¹ -> Pure +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call -⁰@result¹ @ test² -> Pure +//│ deforest > call -⁰@result¹ @ test³ -> Pure +//│ deforest > call -⁰@result¹ @ test¹ -> Pure +//│ deforest > call test⁰@result⁴ @ -> UnsafeEta +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> @@ -287,24 +287,24 @@ fun aa(x) = AA(x) let cc = CC("cc") f1(aa(BB(cc))) + f2(aa(BB(CC(0)))) + f3(cc) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function aa#0 @ aa@aa -> UnsafeEta -//│ deforest > function aa#0 @ aa@aa -> UnsafeEta -//│ deforest > function aa#0 @ aa@aa -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f3@f3 -> Pure -//│ deforest > call +@result @ f3@f3 -> Pure -//│ deforest > call aa@result @ -> UnsafeEta -//│ deforest > call aa@result @ -> UnsafeEta -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call f3@result @ -> UnsafeEta +//│ deforest > function aa⁰#0 @ aa² -> UnsafeEta +//│ deforest > function aa⁰#0 @ aa³ -> UnsafeEta +//│ deforest > function aa⁰#0 @ aa¹ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3² -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ f3² -> Pure +//│ deforest > call +⁰@result⁰ @ f3¹ -> Pure +//│ deforest > call aa⁰@result⁵ @ -> UnsafeEta +//│ deforest > call aa⁰@result⁷ @ -> UnsafeEta +//│ deforest > call f1⁰@result⁶ @ -> UnsafeEta +//│ deforest > call f2⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f3⁰@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x⁸) -> @@ -330,11 +330,11 @@ fun c(x, y) = if x is let y = A in c(AA(2), y) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c¹ -> Pure +//│ deforest > call c⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> @@ -356,17 +356,17 @@ fun c2(y) = if y is A then 3 let y = A in c(AA(2), y) + c2(y) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c2@result @ -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2¹ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ c² -> Pure +//│ deforest > call +⁰@result¹ @ c¹ -> Pure +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c¹ -> Pure +//│ deforest > call c2⁰@result³ @ -> UnsafeEta +//│ deforest > call c⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> @@ -389,19 +389,19 @@ fun f(a) = if a is let p = AA(AA(AA("10"))) test(p) + f(p) + test(AA(A)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call f⁰@result⁴ @ -> UnsafeEta +//│ deforest > call test⁰@result² @ -> UnsafeEta +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(A⁰) -> @@ -430,18 +430,18 @@ fun f(x, y) = let aa = AA(3) f(aa, 3) + f(aa, 4) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ f² -> Pure +//│ deforest > call +⁰@result¹ @ f³ -> Pure +//│ deforest > call +⁰@result¹ @ f¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call f⁰@result³ @ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(tmp⁸) -> @@ -485,18 +485,18 @@ fun test(n, p, q) = AA(y) then k + y test(3, AA(2), AA(3)) + test(3, AA(2), AA(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ test² -> Pure +//│ deforest > call +⁰@result¹ @ test³ -> Pure +//│ deforest > call +⁰@result¹ @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call test⁰@result³ @ -> UnsafeEta +//│ deforest > call test⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(0) -> @@ -539,22 +539,22 @@ let a = A fun c(a) = if a is A then 0 test(1, AA(2), AA(3), a) + test(2, AA(2), AA(3), a) + c(a) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ test² -> Pure +//│ deforest > call +⁰@result¹ @ test³ -> Pure +//│ deforest > call +⁰@result¹ @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call c⁰@result³ @ -> UnsafeEta +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta +//│ deforest > call test⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(3) -> @@ -587,24 +587,24 @@ fun test(x, y, z, i) = k + i test(AA(1), AA(2), BB(3), 4) + test(AA(1), AA(2), BB(3), 4) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ test² -> Pure +//│ deforest > call +⁰@result² @ test³ -> Pure +//│ deforest > call +⁰@result² @ test¹ -> Pure +//│ deforest > call +⁰@result³ @ test² -> Pure +//│ deforest > call +⁰@result³ @ test³ -> Pure +//│ deforest > call +⁰@result³ @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call -⁰@result¹ @ test² -> Pure +//│ deforest > call -⁰@result¹ @ test³ -> Pure +//│ deforest > call -⁰@result¹ @ test¹ -> Pure +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta +//│ deforest > call test⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> @@ -642,27 +642,27 @@ fun test(x, y, z, i) = k + i test(AA(1), AA(2), BB(3), 4) + test(AA(1), BB(2), BB(3), 4) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ test² -> Pure +//│ deforest > call +⁰@result³ @ test³ -> Pure +//│ deforest > call +⁰@result³ @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call +⁰@result⁴ @ test² -> Pure +//│ deforest > call +⁰@result⁴ @ test³ -> Pure +//│ deforest > call +⁰@result⁴ @ test¹ -> Pure +//│ deforest > call +⁰@result⁵ @ -> Pure +//│ deforest > call -⁰@result² @ test² -> Pure +//│ deforest > call -⁰@result² @ test³ -> Pure +//│ deforest > call -⁰@result² @ test¹ -> Pure +//│ deforest > call -⁰@result¹ @ test² -> Pure +//│ deforest > call -⁰@result¹ @ test³ -> Pure +//│ deforest > call -⁰@result¹ @ test¹ -> Pure +//│ deforest > call test⁰@result⁶ @ -> UnsafeEta +//│ deforest > call test⁰@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> @@ -698,26 +698,26 @@ fun c(x) = if x is AA then 0 fun p(x) = AA(x) test(p(BB(3))) + test(p(CC(3))) + c(p(A)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p²#0 @ p³ -> UnsafeEta +//│ deforest > function p²#0 @ p⁴ -> UnsafeEta +//│ deforest > function p²#0 @ p⁵ -> UnsafeEta +//│ deforest > function p²#0 @ p⁶ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call c⁰@result² @ -> UnsafeEta +//│ deforest > call p²@result³ @ -> UnsafeEta +//│ deforest > call p²@result⁶ @ -> UnsafeEta +//│ deforest > call p²@result⁸ @ -> UnsafeEta +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta +//│ deforest > call test⁰@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x¹⁶) -> @@ -755,24 +755,24 @@ fun f(x, y, z, k) = AA then m + k f(AA(3), 3, true, 10) + f(AA(5), 4, false, 20) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ f² -> Pure +//│ deforest > call +⁰@result² @ f³ -> Pure +//│ deforest > call +⁰@result² @ f¹ -> Pure +//│ deforest > call +⁰@result³ @ f² -> Pure +//│ deforest > call +⁰@result³ @ f³ -> Pure +//│ deforest > call +⁰@result³ @ f¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call -⁰@result¹ @ f² -> Pure +//│ deforest > call -⁰@result¹ @ f³ -> Pure +//│ deforest > call -⁰@result¹ @ f¹ -> Pure +//│ deforest > call f⁰@result⁵ @ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(tmp¹⁰) -> @@ -827,15 +827,15 @@ fun f(a) = if a is let p = AA(AA(AA(10))) test(p) + f(p) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call f⁰@result² @ -> UnsafeEta +//│ deforest > call test⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -857,21 +857,21 @@ fun test(a, b) = print(x) test(B, B) + test(A, A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call print@result @ test@test -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call print@result² @ test² -> UnsafeEta +//│ deforest > call print@result² @ test³ -> UnsafeEta +//│ deforest > call print@result² @ test¹ -> UnsafeEta +//│ deforest > call print@result¹ @ test² -> UnsafeEta +//│ deforest > call print@result¹ @ test³ -> UnsafeEta +//│ deforest > call print@result¹ @ test¹ -> UnsafeEta +//│ deforest > call print@result⁰ @ test² -> UnsafeEta +//│ deforest > call print@result⁰ @ test³ -> UnsafeEta +//│ deforest > call print@result⁰ @ test¹ -> UnsafeEta +//│ deforest > call test⁰@result⁴ @ -> UnsafeEta +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -901,20 +901,20 @@ fun sum(ls) = if ls is h :: t then h + sum(t) sum(prodDouble(4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function prodDouble#0 @ prodDouble@prodDouble -> UnsafeEta -//│ deforest > function prodDouble#0 @ prodDouble@prodDouble -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call -@result @ prodDouble@prodDouble -> Pure -//│ deforest > call -@result @ prodDouble@prodDouble -> Pure -//│ deforest > call prodDouble@result @ -> UnsafeEta -//│ deforest > call prodDouble@result @ prodDouble@prodDouble -> UnsafeEta -//│ deforest > call prodDouble@result @ prodDouble@prodDouble -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function prodDouble⁰#0 @ prodDouble² -> UnsafeEta +//│ deforest > function prodDouble⁰#0 @ prodDouble¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ sum² -> Pure +//│ deforest > call +⁰@result¹ @ sum¹ -> Pure +//│ deforest > call -⁰@result² @ prodDouble² -> Pure +//│ deforest > call -⁰@result² @ prodDouble¹ -> Pure +//│ deforest > call prodDouble⁰@result³ @ prodDouble² -> UnsafeEta +//│ deforest > call prodDouble⁰@result³ @ prodDouble¹ -> UnsafeEta +//│ deforest > call prodDouble⁰@result⁵ @ -> UnsafeEta +//│ deforest > call sum⁰@result⁰ @ sum² -> UnsafeEta +//│ deforest > call sum⁰@result⁰ @ sum¹ -> UnsafeEta +//│ deforest > call sum⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -942,22 +942,22 @@ fun cons(ls) = if ls is _ then 0 cons(prod(4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function cons#0 @ cons@cons -> UnsafeEta -//│ deforest > function cons#0 @ cons@cons -> UnsafeEta -//│ deforest > function prod#0 @ prod@prod -> UnsafeEta -//│ deforest > function prod#0 @ prod@prod -> UnsafeEta -//│ deforest > call +@result @ cons@cons -> Pure -//│ deforest > call +@result @ cons@cons -> Pure -//│ deforest > call +@result @ cons@cons -> Pure -//│ deforest > call +@result @ cons@cons -> Pure -//│ deforest > call -@result @ prod@prod -> Pure -//│ deforest > call -@result @ prod@prod -> Pure -//│ deforest > call cons@result @ -> UnsafeEta -//│ deforest > call cons@result @ cons@cons -> UnsafeEta -//│ deforest > call cons@result @ cons@cons -> UnsafeEta -//│ deforest > call prod@result @ -> UnsafeEta -//│ deforest > call prod@result @ prod@prod -> UnsafeEta -//│ deforest > call prod@result @ prod@prod -> UnsafeEta +//│ deforest > function cons⁰#0 @ cons² -> UnsafeEta +//│ deforest > function cons⁰#0 @ cons¹ -> UnsafeEta +//│ deforest > function prod⁰#0 @ prod² -> UnsafeEta +//│ deforest > function prod⁰#0 @ prod¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ cons² -> Pure +//│ deforest > call +⁰@result² @ cons¹ -> Pure +//│ deforest > call +⁰@result⁰ @ cons² -> Pure +//│ deforest > call +⁰@result⁰ @ cons¹ -> Pure +//│ deforest > call -⁰@result³ @ prod² -> Pure +//│ deforest > call -⁰@result³ @ prod¹ -> Pure +//│ deforest > call cons⁰@result¹ @ cons² -> UnsafeEta +//│ deforest > call cons⁰@result¹ @ cons¹ -> UnsafeEta +//│ deforest > call cons⁰@result⁵ @ -> UnsafeEta +//│ deforest > call prod⁰@result⁴ @ prod² -> UnsafeEta +//│ deforest > call prod⁰@result⁴ @ prod¹ -> UnsafeEta +//│ deforest > call prod⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< diff --git a/hkmc2/shared/src/test/mlscript/deforest/recursive.mls b/hkmc2/shared/src/test/mlscript/deforest/recursive.mls index 96a69bc9ca..1d5cb9cfcb 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/recursive.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/recursive.mls @@ -25,17 +25,17 @@ fun map(f, ls_map) = if ls_map is let c = Cons(1, Nil) in map(x => x + 1, c) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ lambda² -> Pure +//│ deforest > call +⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call f⁰@result¹ @ map² -> Pure +//│ deforest > call f⁰@result¹ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result² @ map² -> UnsafeEta +//│ deforest > call map⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, Nil⁰) -> @@ -54,20 +54,20 @@ fun map(f, ls_map) = if ls_map is fun c(a) = Cons(a, Nil) map(x => x + 1, c(1)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ lambda² -> Pure +//│ deforest > call +⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call c⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ map² -> Pure +//│ deforest > call f⁰@result¹ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result² @ map² -> UnsafeEta +//│ deforest > call map⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁰, Nil⁰) -> @@ -86,17 +86,17 @@ fun map(ls, f) = if ls is h :: t then f(h) :: map(t, f) map(1 :: 2 :: Nil, x => x + 1) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ lambda² -> Pure +//│ deforest > call +⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call f⁰@result¹ @ map² -> Pure +//│ deforest > call f⁰@result¹ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result² @ map² -> UnsafeEta +//│ deforest > call map⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, tmp⁰) -> @@ -119,22 +119,22 @@ fun sum(ls) = if ls is fun enum(n) = if n > 0 then n :: enum(n - 1) else Nil sum(enum(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call >@result @ enum@enum -> Pure -//│ deforest > call >@result @ enum@enum -> Pure -//│ deforest > call enum@result @ -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum² -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum¹ -> UnsafeEta +//│ deforest > call +⁰@result⁴ @ sum² -> Pure +//│ deforest > call +⁰@result⁴ @ sum¹ -> Pure +//│ deforest > call -⁰@result¹ @ enum² -> Pure +//│ deforest > call -⁰@result¹ @ enum¹ -> Pure +//│ deforest > call >⁰@result⁰ @ enum² -> Pure +//│ deforest > call >⁰@result⁰ @ enum¹ -> Pure +//│ deforest > call enum⁰@result² @ enum² -> UnsafeEta +//│ deforest > call enum⁰@result² @ enum¹ -> UnsafeEta +//│ deforest > call enum⁰@result⁶ @ -> UnsafeEta +//│ deforest > call sum⁰@result³ @ sum² -> UnsafeEta +//│ deforest > call sum⁰@result³ @ sum¹ -> UnsafeEta +//│ deforest > call sum⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(n⁰, tmp¹) -> @@ -153,26 +153,26 @@ fun map(ls, f) = if ls is h :: t then f(h) :: map(t, f) map(map(id(1 :: 2 :: Nil), x => x + 1), x => x * 2) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call *@result @ lambda@lambda -> Pure -//│ deforest > call *@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function lambda²#0 @ lambda³ -> Pure +//│ deforest > function lambda²#0 @ lambda⁵ -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function lambda⁰#0 @ lambda⁴ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map³ -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call *⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call *⁰@result⁰ @ lambda⁴ -> Pure +//│ deforest > call +⁰@result¹ @ lambda³ -> Pure +//│ deforest > call +⁰@result¹ @ lambda⁵ -> Pure +//│ deforest > call f⁰@result² @ map² -> Pure +//│ deforest > call f⁰@result² @ map³ -> Pure +//│ deforest > call f⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call id@result⁶ @ -> UnsafeEta +//│ deforest > call map⁰@result³ @ map² -> UnsafeEta +//│ deforest > call map⁰@result³ @ map³ -> UnsafeEta +//│ deforest > call map⁰@result³ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁴ @ -> UnsafeEta +//│ deforest > call map⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -191,35 +191,35 @@ fun map(f, ls) = if ls is fun enum(a) = if a < 0 then Nil else a :: enum(a - 1) map(x => x + 1, map(x => x * 2, id(enum(3)))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function enum#0 @ enum@enum -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call *@result @ lambda@lambda -> Pure -//│ deforest > call *@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call -@result @ enum@enum -> Pure -//│ deforest > call <@result @ enum@enum -> Pure -//│ deforest > call <@result @ enum@enum -> Pure -//│ deforest > call enum@result @ -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call enum@result @ enum@enum -> UnsafeEta -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum² -> UnsafeEta +//│ deforest > function enum⁰#0 @ enum¹ -> UnsafeEta +//│ deforest > function lambda²#0 @ lambda³ -> Pure +//│ deforest > function lambda²#0 @ lambda⁴ -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function lambda⁰#0 @ lambda⁵ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map³ -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call *⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call *⁰@result⁰ @ lambda⁵ -> Pure +//│ deforest > call +⁰@result¹ @ lambda³ -> Pure +//│ deforest > call +⁰@result¹ @ lambda⁴ -> Pure +//│ deforest > call -⁰@result³ @ enum² -> Pure +//│ deforest > call -⁰@result³ @ enum¹ -> Pure +//│ deforest > call <⁰@result² @ enum² -> Pure +//│ deforest > call <⁰@result² @ enum¹ -> Pure +//│ deforest > call enum⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call enum⁰@result⁴ @ enum² -> UnsafeEta +//│ deforest > call enum⁰@result⁴ @ enum¹ -> UnsafeEta +//│ deforest > call f⁰@result⁵ @ map² -> Pure +//│ deforest > call f⁰@result⁵ @ map³ -> Pure +//│ deforest > call f⁰@result⁵ @ map¹ -> UnsafeEta +//│ deforest > call id@result⁹ @ -> UnsafeEta +//│ deforest > call map⁰@result⁶ @ map² -> UnsafeEta +//│ deforest > call map⁰@result⁶ @ map³ -> UnsafeEta +//│ deforest > call map⁰@result⁶ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁷ @ -> UnsafeEta +//│ deforest > call map⁰@result⁸ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -245,55 +245,55 @@ fun cons1(a1) = if a1 is h :: t then h + cons1(t) cons(f(0)) + cons1(f(1)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function cons#0 @ cons@cons -> UnsafeEta -//│ deforest > function cons#0 @ cons@cons -> UnsafeEta -//│ deforest > function cons1#0 @ cons1@cons1 -> UnsafeEta -//│ deforest > function cons1#0 @ cons1@cons1 -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ cons1@cons1 -> Pure -//│ deforest > call +@result @ cons1@cons1 -> Pure -//│ deforest > call +@result @ cons@cons -> Pure -//│ deforest > call +@result @ cons@cons -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ g@g -> Pure -//│ deforest > call -@result @ g@g -> Pure -//│ deforest > call cons1@result @ -> UnsafeEta -//│ deforest > call cons1@result @ cons1@cons1 -> UnsafeEta -//│ deforest > call cons1@result @ cons1@cons1 -> UnsafeEta -//│ deforest > call cons@result @ -> UnsafeEta -//│ deforest > call cons@result @ cons@cons -> UnsafeEta -//│ deforest > call cons@result @ cons@cons -> UnsafeEta -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ g@g -> UnsafeEta -//│ deforest > call equals@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > function cons1⁰#0 @ cons1² -> UnsafeEta +//│ deforest > function cons1⁰#0 @ cons1¹ -> UnsafeEta +//│ deforest > function cons⁰#0 @ cons² -> UnsafeEta +//│ deforest > function cons⁰#0 @ cons¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ g⁰ -> UnsafeEta +//│ deforest > function g¹#0 @ f² -> UnsafeEta +//│ deforest > function g¹#0 @ f³ -> UnsafeEta +//│ deforest > function g¹#0 @ f¹ -> UnsafeEta +//│ deforest > function g¹#0 @ g⁰ -> UnsafeEta +//│ deforest > call +⁰@result³ @ cons² -> Pure +//│ deforest > call +⁰@result³ @ cons¹ -> Pure +//│ deforest > call +⁰@result¹ @ cons1² -> Pure +//│ deforest > call +⁰@result¹ @ cons1¹ -> Pure +//│ deforest > call +⁰@result¹⁰ @ -> Pure +//│ deforest > call -⁰@result⁵ @ f² -> Pure +//│ deforest > call -⁰@result⁵ @ f³ -> Pure +//│ deforest > call -⁰@result⁵ @ f¹ -> Pure +//│ deforest > call -⁰@result⁵ @ g⁰ -> Pure +//│ deforest > call -⁰@result⁸ @ f² -> Pure +//│ deforest > call -⁰@result⁸ @ f³ -> Pure +//│ deforest > call -⁰@result⁸ @ f¹ -> Pure +//│ deforest > call -⁰@result⁸ @ g⁰ -> Pure +//│ deforest > call cons1⁰@result¹¹ @ -> UnsafeEta +//│ deforest > call cons1⁰@result⁰ @ cons1² -> UnsafeEta +//│ deforest > call cons1⁰@result⁰ @ cons1¹ -> UnsafeEta +//│ deforest > call cons⁰@result² @ cons² -> UnsafeEta +//│ deforest > call cons⁰@result² @ cons¹ -> UnsafeEta +//│ deforest > call cons⁰@result¹³ @ -> UnsafeEta +//│ deforest > call equals@result⁴ @ f² -> UnsafeEta +//│ deforest > call equals@result⁴ @ f³ -> UnsafeEta +//│ deforest > call equals@result⁴ @ f¹ -> UnsafeEta +//│ deforest > call equals@result⁴ @ g⁰ -> UnsafeEta +//│ deforest > call equals@result⁷ @ f² -> UnsafeEta +//│ deforest > call equals@result⁷ @ f³ -> UnsafeEta +//│ deforest > call equals@result⁷ @ f¹ -> UnsafeEta +//│ deforest > call equals@result⁷ @ g⁰ -> UnsafeEta +//│ deforest > call f⁰@result¹² @ -> UnsafeEta +//│ deforest > call f⁰@result¹⁴ @ -> UnsafeEta +//│ deforest > call f⁰@result⁹ @ f² -> UnsafeEta +//│ deforest > call f⁰@result⁹ @ f³ -> UnsafeEta +//│ deforest > call f⁰@result⁹ @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result⁹ @ g⁰ -> UnsafeEta +//│ deforest > call g¹@result⁶ @ f² -> UnsafeEta +//│ deforest > call g¹@result⁶ @ f³ -> UnsafeEta +//│ deforest > call g¹@result⁶ @ f¹ -> UnsafeEta +//│ deforest > call g¹@result⁶ @ g⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -337,22 +337,22 @@ fun f1(ls1) = if ls1 is Nil then 2 f1(to(4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f1@result @ f1@f1 -> UnsafeEta -//│ deforest > call f1@result @ f1@f1 -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ to² -> UnsafeEta +//│ deforest > function to⁰#0 @ to¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ f1² -> Pure +//│ deforest > call +⁰@result¹ @ f1¹ -> Pure +//│ deforest > call -⁰@result³ @ to² -> Pure +//│ deforest > call -⁰@result³ @ to¹ -> Pure +//│ deforest > call >⁰@result² @ to² -> Pure +//│ deforest > call >⁰@result² @ to¹ -> Pure +//│ deforest > call f1⁰@result⁰ @ f1² -> UnsafeEta +//│ deforest > call f1⁰@result⁰ @ f1¹ -> UnsafeEta +//│ deforest > call f1⁰@result⁵ @ -> UnsafeEta +//│ deforest > call to⁰@result⁴ @ to² -> UnsafeEta +//│ deforest > call to⁰@result⁴ @ to¹ -> UnsafeEta +//│ deforest > call to⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(n¹, tmp⁸) -> @@ -372,25 +372,25 @@ fun succ(x) = x + 1 fun double(x) = x * 2 map(map(1 :: 2 :: Nil, succ), double) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function double#0 @ double@double -> Pure -//│ deforest > function double#0 @ double@double -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function succ#0 @ succ@succ -> Pure -//│ deforest > function succ#0 @ succ@succ -> Pure -//│ deforest > call *@result @ double@double -> Pure -//│ deforest > call *@result @ double@double -> Pure -//│ deforest > call +@result @ succ@succ -> Pure -//│ deforest > call +@result @ succ@succ -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function double⁰#0 @ double² -> Pure +//│ deforest > function double⁰#0 @ double¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map³ -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > function succ⁰#0 @ succ² -> Pure +//│ deforest > function succ⁰#0 @ succ¹ -> Pure +//│ deforest > call *⁰@result⁰ @ double² -> Pure +//│ deforest > call *⁰@result⁰ @ double¹ -> Pure +//│ deforest > call +⁰@result¹ @ succ² -> Pure +//│ deforest > call +⁰@result¹ @ succ¹ -> Pure +//│ deforest > call f⁰@result² @ map² -> Pure +//│ deforest > call f⁰@result² @ map³ -> Pure +//│ deforest > call f⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result³ @ map² -> UnsafeEta +//│ deforest > call map⁰@result³ @ map³ -> UnsafeEta +//│ deforest > call map⁰@result³ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁴ @ -> UnsafeEta +//│ deforest > call map⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -423,39 +423,39 @@ fun f2(ls) = if ls is fun wrap(n) = to(n) f1(wrap(4)) + f2(wrap(5)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ wrap@wrap.to@to -> UnsafeEta -//│ deforest > function to#0 @ wrap@wrap.to@to -> UnsafeEta -//│ deforest > function to#0 @ wrap@wrap.to@to -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ wrap@wrap.to@to -> Pure -//│ deforest > call -@result @ wrap@wrap.to@to -> Pure -//│ deforest > call -@result @ wrap@wrap.to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call >@result @ wrap@wrap.to@to -> Pure -//│ deforest > call >@result @ wrap@wrap.to@to -> Pure -//│ deforest > call >@result @ wrap@wrap.to@to -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ wrap@wrap -> UnsafeEta -//│ deforest > call to@result @ wrap@wrap -> UnsafeEta -//│ deforest > call to@result @ wrap@wrap -> UnsafeEta -//│ deforest > call to@result @ wrap@wrap.to@to -> UnsafeEta -//│ deforest > call to@result @ wrap@wrap.to@to -> UnsafeEta -//│ deforest > call to@result @ wrap@wrap.to@to -> UnsafeEta -//│ deforest > call wrap@result @ -> UnsafeEta -//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ to² -> UnsafeEta +//│ deforest > function to⁰#0 @ wrap².to¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ wrap³.to¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ wrap⁰.to¹ -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap² -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap³ -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap⁰ -> UnsafeEta +//│ deforest > call +⁰@result⁴ @ f2² -> Pure +//│ deforest > call +⁰@result⁴ @ f2¹ -> Pure +//│ deforest > call +⁰@result⁵ @ -> Pure +//│ deforest > call -⁰@result¹ @ to² -> Pure +//│ deforest > call -⁰@result¹ @ wrap².to¹ -> Pure +//│ deforest > call -⁰@result¹ @ wrap³.to¹ -> Pure +//│ deforest > call -⁰@result¹ @ wrap⁰.to¹ -> Pure +//│ deforest > call >⁰@result² @ to² -> Pure +//│ deforest > call >⁰@result² @ wrap².to¹ -> Pure +//│ deforest > call >⁰@result² @ wrap³.to¹ -> Pure +//│ deforest > call >⁰@result² @ wrap⁰.to¹ -> Pure +//│ deforest > call f1⁰@result⁸ @ -> UnsafeEta +//│ deforest > call f2⁰@result⁶ @ -> UnsafeEta +//│ deforest > call to⁰@result³ @ wrap² -> UnsafeEta +//│ deforest > call to⁰@result³ @ wrap³ -> UnsafeEta +//│ deforest > call to⁰@result³ @ wrap⁰ -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ to² -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ wrap².to¹ -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ wrap³.to¹ -> UnsafeEta +//│ deforest > call to⁰@result⁰ @ wrap⁰.to¹ -> UnsafeEta +//│ deforest > call wrap¹@result⁷ @ -> UnsafeEta +//│ deforest > call wrap¹@result⁹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -483,47 +483,47 @@ fun f2(ls, acc) = if ls is h :: t then f2(t, acc + h + 1) f1(to(4, Nil), 0) + f2(to(5, Nil), 0) + f1(to(6, Nil), 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call equals@result @ to@to -> UnsafeEta -//│ deforest > call equals@result @ to@to -> UnsafeEta -//│ deforest > call equals@result @ to@to -> UnsafeEta -//│ deforest > call equals@result @ to@to -> UnsafeEta -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f1@result @ f1@f1 -> UnsafeEta -//│ deforest > call f1@result @ f1@f1 -> UnsafeEta -//│ deforest > call f1@result @ f1@f1 -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call f2@result @ f2@f2 -> UnsafeEta -//│ deforest > call f2@result @ f2@f2 -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1³ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ to² -> UnsafeEta +//│ deforest > function to⁰#0 @ to³ -> UnsafeEta +//│ deforest > function to⁰#0 @ to¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ to⁴ -> UnsafeEta +//│ deforest > call +⁰@result³ @ f1² -> Pure +//│ deforest > call +⁰@result³ @ f1³ -> Pure +//│ deforest > call +⁰@result³ @ f1¹ -> Pure +//│ deforest > call +⁰@result¹ @ f2² -> Pure +//│ deforest > call +⁰@result¹ @ f2¹ -> Pure +//│ deforest > call +⁰@result¹¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ f2² -> Pure +//│ deforest > call +⁰@result⁰ @ f2¹ -> Pure +//│ deforest > call +⁰@result⁸ @ -> Pure +//│ deforest > call -⁰@result⁶ @ to² -> Pure +//│ deforest > call -⁰@result⁶ @ to³ -> Pure +//│ deforest > call -⁰@result⁶ @ to¹ -> Pure +//│ deforest > call -⁰@result⁶ @ to⁴ -> Pure +//│ deforest > call equals@result⁵ @ to² -> UnsafeEta +//│ deforest > call equals@result⁵ @ to³ -> UnsafeEta +//│ deforest > call equals@result⁵ @ to¹ -> UnsafeEta +//│ deforest > call equals@result⁵ @ to⁴ -> UnsafeEta +//│ deforest > call f1⁰@result¹⁴ @ -> UnsafeEta +//│ deforest > call f1⁰@result⁴ @ f1² -> UnsafeEta +//│ deforest > call f1⁰@result⁴ @ f1³ -> UnsafeEta +//│ deforest > call f1⁰@result⁴ @ f1¹ -> UnsafeEta +//│ deforest > call f1⁰@result⁹ @ -> UnsafeEta +//│ deforest > call f2⁰@result² @ f2² -> UnsafeEta +//│ deforest > call f2⁰@result² @ f2¹ -> UnsafeEta +//│ deforest > call f2⁰@result¹² @ -> UnsafeEta +//│ deforest > call to⁰@result¹³ @ -> UnsafeEta +//│ deforest > call to⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call to⁰@result¹⁵ @ -> UnsafeEta +//│ deforest > call to⁰@result⁷ @ to² -> UnsafeEta +//│ deforest > call to⁰@result⁷ @ to³ -> UnsafeEta +//│ deforest > call to⁰@result⁷ @ to¹ -> UnsafeEta +//│ deforest > call to⁰@result⁷ @ to⁴ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -556,33 +556,33 @@ fun double(x) = x * 2 fun triple(x) = x * 3 map(map(map(1 :: 2 :: Nil, succ), double), triple) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function double#0 @ double@double -> Pure -//│ deforest > function double#0 @ double@double -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function succ#0 @ succ@succ -> Pure -//│ deforest > function succ#0 @ succ@succ -> Pure -//│ deforest > function triple#0 @ triple@triple -> Pure -//│ deforest > function triple#0 @ triple@triple -> Pure -//│ deforest > call *@result @ double@double -> Pure -//│ deforest > call *@result @ double@double -> Pure -//│ deforest > call *@result @ triple@triple -> Pure -//│ deforest > call *@result @ triple@triple -> Pure -//│ deforest > call +@result @ succ@succ -> Pure -//│ deforest > call +@result @ succ@succ -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function double⁰#0 @ double² -> Pure +//│ deforest > function double⁰#0 @ double¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map³ -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > function map⁰#0 @ map⁴ -> UnsafeEta +//│ deforest > function succ⁰#0 @ succ² -> Pure +//│ deforest > function succ⁰#0 @ succ¹ -> Pure +//│ deforest > function triple⁰#0 @ triple² -> Pure +//│ deforest > function triple⁰#0 @ triple¹ -> Pure +//│ deforest > call *⁰@result¹ @ double² -> Pure +//│ deforest > call *⁰@result¹ @ double¹ -> Pure +//│ deforest > call *⁰@result⁰ @ triple² -> Pure +//│ deforest > call *⁰@result⁰ @ triple¹ -> Pure +//│ deforest > call +⁰@result² @ succ² -> Pure +//│ deforest > call +⁰@result² @ succ¹ -> Pure +//│ deforest > call f⁰@result³ @ map² -> Pure +//│ deforest > call f⁰@result³ @ map³ -> Pure +//│ deforest > call f⁰@result³ @ map¹ -> UnsafeEta +//│ deforest > call f⁰@result³ @ map⁴ -> Pure +//│ deforest > call map⁰@result⁴ @ map² -> UnsafeEta +//│ deforest > call map⁰@result⁴ @ map³ -> UnsafeEta +//│ deforest > call map⁰@result⁴ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁴ @ map⁴ -> UnsafeEta +//│ deforest > call map⁰@result⁵ @ -> UnsafeEta +//│ deforest > call map⁰@result⁶ @ -> UnsafeEta +//│ deforest > call map⁰@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -625,38 +625,38 @@ fun incr(x) = x + 1 fun double(x) = x * 2 map1(incr, map(double, id(mk(5)))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function double#0 @ double@double -> Pure -//│ deforest > function double#0 @ double@double -> Pure -//│ deforest > function incr#0 @ incr@incr -> Pure -//│ deforest > function incr#0 @ incr@incr -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map1#0 @ map1@map1 -> UnsafeEta -//│ deforest > function map1#0 @ map1@map1 -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > call *@result @ double@double -> Pure -//│ deforest > call *@result @ double@double -> Pure -//│ deforest > call +@result @ incr@incr -> Pure -//│ deforest > call +@result @ incr@incr -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call <@result @ mk@mk -> Pure -//│ deforest > call <@result @ mk@mk -> Pure -//│ deforest > call f@result @ map1@map1 -> Pure -//│ deforest > call f@result @ map1@map1 -> UnsafeEta -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call map1@result @ -> UnsafeEta -//│ deforest > call map1@result @ map1@map1 -> UnsafeEta -//│ deforest > call map1@result @ map1@map1 -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call mk@result @ -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta +//│ deforest > function double⁰#0 @ double² -> Pure +//│ deforest > function double⁰#0 @ double¹ -> Pure +//│ deforest > function incr⁰#0 @ incr² -> Pure +//│ deforest > function incr⁰#0 @ incr¹ -> Pure +//│ deforest > function map1⁰#0 @ map1² -> UnsafeEta +//│ deforest > function map1⁰#0 @ map1¹ -> UnsafeEta +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk² -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk¹ -> UnsafeEta +//│ deforest > call *⁰@result⁰ @ double² -> Pure +//│ deforest > call *⁰@result⁰ @ double¹ -> Pure +//│ deforest > call +⁰@result¹ @ incr² -> Pure +//│ deforest > call +⁰@result¹ @ incr¹ -> Pure +//│ deforest > call -⁰@result⁷ @ mk² -> Pure +//│ deforest > call -⁰@result⁷ @ mk¹ -> Pure +//│ deforest > call <⁰@result⁶ @ mk² -> Pure +//│ deforest > call <⁰@result⁶ @ mk¹ -> Pure +//│ deforest > call f¹@result⁴ @ map² -> Pure +//│ deforest > call f¹@result⁴ @ map¹ -> UnsafeEta +//│ deforest > call f⁰@result² @ map1² -> Pure +//│ deforest > call f⁰@result² @ map1¹ -> UnsafeEta +//│ deforest > call id@result¹¹ @ -> UnsafeEta +//│ deforest > call map1⁰@result³ @ map1² -> UnsafeEta +//│ deforest > call map1⁰@result³ @ map1¹ -> UnsafeEta +//│ deforest > call map1⁰@result⁹ @ -> UnsafeEta +//│ deforest > call map⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call map⁰@result⁵ @ map² -> UnsafeEta +//│ deforest > call map⁰@result⁵ @ map¹ -> UnsafeEta +//│ deforest > call mk⁰@result¹² @ -> UnsafeEta +//│ deforest > call mk⁰@result⁸ @ mk² -> UnsafeEta +//│ deforest > call mk⁰@result⁸ @ mk¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(tmp¹⁶, tmp¹⁷) -> @@ -677,22 +677,22 @@ fun map(ls) = if ls is h :: t then (h + 4) :: map(t) map(enumFromTo(1, 4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ map@map -> Pure -//│ deforest > call +@result @ map@map -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call enumFromTo@result @ -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo¹ -> UnsafeEta +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ enumFromTo² -> Pure +//│ deforest > call +⁰@result³ @ enumFromTo¹ -> Pure +//│ deforest > call +⁰@result⁰ @ map² -> Pure +//│ deforest > call +⁰@result⁰ @ map¹ -> Pure +//│ deforest > call <⁰@result² @ enumFromTo² -> Pure +//│ deforest > call <⁰@result² @ enumFromTo¹ -> Pure +//│ deforest > call enumFromTo⁰@result⁴ @ enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁴ @ enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ -> UnsafeEta +//│ deforest > call map⁰@result¹ @ map² -> UnsafeEta +//│ deforest > call map⁰@result¹ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a², tmp¹⁸) -> @@ -711,22 +711,22 @@ fun sum(ls) = if ls is h :: t then h + sum(t) sum(enumFromTo(1,10)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call enumFromTo@result @ -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ enumFromTo² -> Pure +//│ deforest > call +⁰@result³ @ enumFromTo¹ -> Pure +//│ deforest > call +⁰@result¹ @ sum² -> Pure +//│ deforest > call +⁰@result¹ @ sum¹ -> Pure +//│ deforest > call <⁰@result² @ enumFromTo² -> Pure +//│ deforest > call <⁰@result² @ enumFromTo¹ -> Pure +//│ deforest > call enumFromTo⁰@result⁴ @ enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁴ @ enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ -> UnsafeEta +//│ deforest > call sum⁰@result⁰ @ sum² -> UnsafeEta +//│ deforest > call sum⁰@result⁰ @ sum¹ -> UnsafeEta +//│ deforest > call sum⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a³, tmp¹⁹) -> @@ -746,26 +746,26 @@ fun map(f, ls) = h :: t then f(h) :: map(f, t) map(x => x + 4, enumFromTo(1, 4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call enumFromTo@result @ -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo¹ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ lambda² -> Pure +//│ deforest > call +⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call +⁰@result⁴ @ enumFromTo² -> Pure +//│ deforest > call +⁰@result⁴ @ enumFromTo¹ -> Pure +//│ deforest > call <⁰@result³ @ enumFromTo² -> Pure +//│ deforest > call <⁰@result³ @ enumFromTo¹ -> Pure +//│ deforest > call enumFromTo⁰@result⁵ @ enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁵ @ enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁷ @ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ map² -> Pure +//│ deforest > call f⁰@result¹ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result² @ map² -> UnsafeEta +//│ deforest > call map⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁴, tmp²⁰) -> @@ -786,32 +786,32 @@ fun map(f, ls) = )(f) map(x => x + 4, enumFromTo(1, 4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ map@map -> Pure -//│ deforest > function lambda#0 @ map@map -> Pure -//│ deforest > function lambda#0 @ map@map -> UnsafeEta -//│ deforest > function lambda#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call +@result @ lambda@lambda -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call enumFromTo@result @ -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call tmp@result @ map@map -> UnsafeEta -//│ deforest > call tmp@result @ map@map -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo¹ -> UnsafeEta +//│ deforest > function lambda²#0 @ map² -> Pure +//│ deforest > function lambda²#0 @ map⁰ -> Pure +//│ deforest > function lambda³#0 @ map² -> UnsafeEta +//│ deforest > function lambda³#0 @ map⁰ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function lambda⁰#0 @ lambda⁴ -> Pure +//│ deforest > function map¹#0 @ map² -> UnsafeEta +//│ deforest > function map¹#0 @ map⁰ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call +⁰@result⁰ @ lambda⁴ -> Pure +//│ deforest > call +⁰@result⁵ @ enumFromTo² -> Pure +//│ deforest > call +⁰@result⁵ @ enumFromTo¹ -> Pure +//│ deforest > call <⁰@result⁴ @ enumFromTo² -> Pure +//│ deforest > call <⁰@result⁴ @ enumFromTo¹ -> Pure +//│ deforest > call enumFromTo⁰@result⁶ @ enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁸ @ -> UnsafeEta +//│ deforest > call f⁰@result² @ map² -> Pure +//│ deforest > call f⁰@result² @ map⁰ -> UnsafeEta +//│ deforest > call map¹@result³ @ map² -> UnsafeEta +//│ deforest > call map¹@result³ @ map⁰ -> UnsafeEta +//│ deforest > call map¹@result⁷ @ -> UnsafeEta +//│ deforest > call tmp²¹@result¹ @ map² -> UnsafeEta +//│ deforest > call tmp²¹@result¹ @ map⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁵, tmp²¹) -> @@ -832,22 +832,22 @@ fun sum(ls, a) = if ls is h :: t then sum(t, h + a) sum(enumFromTo(1, 10), 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call enumFromTo@result @ -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo¹ -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ enumFromTo² -> Pure +//│ deforest > call +⁰@result³ @ enumFromTo¹ -> Pure +//│ deforest > call +⁰@result⁰ @ sum² -> Pure +//│ deforest > call +⁰@result⁰ @ sum¹ -> Pure +//│ deforest > call <⁰@result² @ enumFromTo² -> Pure +//│ deforest > call <⁰@result² @ enumFromTo¹ -> Pure +//│ deforest > call enumFromTo⁰@result⁴ @ enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁴ @ enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ -> UnsafeEta +//│ deforest > call sum⁰@result¹ @ sum² -> UnsafeEta +//│ deforest > call sum⁰@result¹ @ sum¹ -> UnsafeEta +//│ deforest > call sum⁰@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(a⁶, tmp²²) -> @@ -872,32 +872,32 @@ fun rev(xs_rev, acc) = if xs_rev is Nil then acc map(incr, rev(id(mk(5)), Nil)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function incr#0 @ incr@incr -> Pure -//│ deforest > function incr#0 @ incr@incr -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function rev#0 @ rev@rev -> UnsafeEta -//│ deforest > function rev#0 @ rev@rev -> UnsafeEta -//│ deforest > call +@result @ incr@incr -> Pure -//│ deforest > call +@result @ incr@incr -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call <@result @ mk@mk -> Pure -//│ deforest > call <@result @ mk@mk -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call mk@result @ -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call rev@result @ -> UnsafeEta -//│ deforest > call rev@result @ rev@rev -> UnsafeEta -//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > function incr⁰#0 @ incr² -> Pure +//│ deforest > function incr⁰#0 @ incr¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk² -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk¹ -> UnsafeEta +//│ deforest > function rev⁰#0 @ rev² -> UnsafeEta +//│ deforest > function rev⁰#0 @ rev¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ incr² -> Pure +//│ deforest > call +⁰@result³ @ incr¹ -> Pure +//│ deforest > call -⁰@result⁵ @ mk² -> Pure +//│ deforest > call -⁰@result⁵ @ mk¹ -> Pure +//│ deforest > call <⁰@result⁴ @ mk² -> Pure +//│ deforest > call <⁰@result⁴ @ mk¹ -> Pure +//│ deforest > call f⁰@result¹ @ map² -> Pure +//│ deforest > call f⁰@result¹ @ map¹ -> UnsafeEta +//│ deforest > call id@result⁹ @ -> UnsafeEta +//│ deforest > call map⁰@result² @ map² -> UnsafeEta +//│ deforest > call map⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁷ @ -> UnsafeEta +//│ deforest > call mk⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call mk⁰@result⁶ @ mk² -> UnsafeEta +//│ deforest > call mk⁰@result⁶ @ mk¹ -> UnsafeEta +//│ deforest > call rev⁰@result⁰ @ rev² -> UnsafeEta +//│ deforest > call rev⁰@result⁰ @ rev¹ -> UnsafeEta +//│ deforest > call rev⁰@result⁸ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -922,32 +922,32 @@ fun rev(xs_rev, acc) = if xs_rev is Nil then acc rev(map(incr, id(mk(3))), Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function incr#0 @ incr@incr -> Pure -//│ deforest > function incr#0 @ incr@incr -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function rev#0 @ rev@rev -> UnsafeEta -//│ deforest > function rev#0 @ rev@rev -> UnsafeEta -//│ deforest > call +@result @ incr@incr -> Pure -//│ deforest > call +@result @ incr@incr -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call <@result @ mk@mk -> Pure -//│ deforest > call <@result @ mk@mk -> Pure -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call mk@result @ -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call rev@result @ -> UnsafeEta -//│ deforest > call rev@result @ rev@rev -> UnsafeEta -//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > function incr⁰#0 @ incr² -> Pure +//│ deforest > function incr⁰#0 @ incr¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk² -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk¹ -> UnsafeEta +//│ deforest > function rev⁰#0 @ rev² -> UnsafeEta +//│ deforest > function rev⁰#0 @ rev¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ incr² -> Pure +//│ deforest > call +⁰@result³ @ incr¹ -> Pure +//│ deforest > call -⁰@result⁵ @ mk² -> Pure +//│ deforest > call -⁰@result⁵ @ mk¹ -> Pure +//│ deforest > call <⁰@result⁴ @ mk² -> Pure +//│ deforest > call <⁰@result⁴ @ mk¹ -> Pure +//│ deforest > call f⁰@result¹ @ map² -> Pure +//│ deforest > call f⁰@result¹ @ map¹ -> UnsafeEta +//│ deforest > call id@result⁹ @ -> UnsafeEta +//│ deforest > call map⁰@result² @ map² -> UnsafeEta +//│ deforest > call map⁰@result² @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁸ @ -> UnsafeEta +//│ deforest > call mk⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call mk⁰@result⁶ @ mk² -> UnsafeEta +//│ deforest > call mk⁰@result⁶ @ mk¹ -> UnsafeEta +//│ deforest > call rev⁰@result⁰ @ rev² -> UnsafeEta +//│ deforest > call rev⁰@result⁰ @ rev¹ -> UnsafeEta +//│ deforest > call rev⁰@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -978,24 +978,24 @@ fun pair_up(xs) = fun mk(n) = if n > 0 then (n - 1) :: n :: (n + 1) :: mk(n - 1) else Nil pair_up(mk(4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function pair_up#0 @ pair_up@pair_up -> UnsafeEta -//│ deforest > function pair_up#0 @ pair_up@pair_up -> UnsafeEta -//│ deforest > call +@result @ mk@mk -> Pure -//│ deforest > call +@result @ mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call >@result @ mk@mk -> Pure -//│ deforest > call >@result @ mk@mk -> Pure -//│ deforest > call mk@result @ -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call pair_up@result @ -> UnsafeEta -//│ deforest > call pair_up@result @ pair_up@pair_up -> UnsafeEta -//│ deforest > call pair_up@result @ pair_up@pair_up -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk² -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk¹ -> UnsafeEta +//│ deforest > function pair_up⁰#0 @ pair_up² -> UnsafeEta +//│ deforest > function pair_up⁰#0 @ pair_up¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ mk² -> Pure +//│ deforest > call +⁰@result² @ mk¹ -> Pure +//│ deforest > call -⁰@result³ @ mk² -> Pure +//│ deforest > call -⁰@result³ @ mk¹ -> Pure +//│ deforest > call -⁰@result¹ @ mk² -> Pure +//│ deforest > call -⁰@result¹ @ mk¹ -> Pure +//│ deforest > call >⁰@result⁰ @ mk² -> Pure +//│ deforest > call >⁰@result⁰ @ mk¹ -> Pure +//│ deforest > call mk⁰@result⁴ @ mk² -> UnsafeEta +//│ deforest > call mk⁰@result⁴ @ mk¹ -> UnsafeEta +//│ deforest > call mk⁰@result⁷ @ -> UnsafeEta +//│ deforest > call pair_up⁰@result⁵ @ pair_up² -> UnsafeEta +//│ deforest > call pair_up⁰@result⁵ @ pair_up¹ -> UnsafeEta +//│ deforest > call pair_up⁰@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1026,50 +1026,50 @@ fun flatten(ls_flatten) = if ls_flatten is x :: xs then append(x, flatten(xs)) sum(flatten(id(mk2d(4)))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function append#0 @ append@append -> UnsafeEta -//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > function append#0 @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta -//│ deforest > function flatten#0 @ flatten@flatten -> UnsafeEta -//│ deforest > function mk#0 @ mk2d@mk2d.mk@mk -> UnsafeEta -//│ deforest > function mk#0 @ mk2d@mk2d.mk@mk -> UnsafeEta -//│ deforest > function mk#0 @ mk@mk -> UnsafeEta -//│ deforest > function mk2d#0 @ mk2d@mk2d -> UnsafeEta -//│ deforest > function mk2d#0 @ mk2d@mk2d -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > function sum#0 @ sum@sum -> UnsafeEta -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call +@result @ sum@sum -> Pure -//│ deforest > call -@result @ mk2d@mk2d -> Pure -//│ deforest > call -@result @ mk2d@mk2d -> Pure -//│ deforest > call -@result @ mk2d@mk2d.mk@mk -> Pure -//│ deforest > call -@result @ mk2d@mk2d.mk@mk -> Pure -//│ deforest > call -@result @ mk@mk -> Pure -//│ deforest > call >@result @ mk2d@mk2d -> Pure -//│ deforest > call >@result @ mk2d@mk2d -> Pure -//│ deforest > call >@result @ mk2d@mk2d.mk@mk -> Pure -//│ deforest > call >@result @ mk2d@mk2d.mk@mk -> Pure -//│ deforest > call >@result @ mk@mk -> Pure -//│ deforest > call append@result @ append@append -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > call append@result @ flatten@flatten.append@append -> UnsafeEta -//│ deforest > call flatten@result @ -> UnsafeEta -//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta -//│ deforest > call flatten@result @ flatten@flatten -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call mk2d@result @ -> UnsafeEta -//│ deforest > call mk2d@result @ mk2d@mk2d -> UnsafeEta -//│ deforest > call mk2d@result @ mk2d@mk2d -> UnsafeEta -//│ deforest > call mk@result @ mk2d@mk2d -> UnsafeEta -//│ deforest > call mk@result @ mk2d@mk2d -> UnsafeEta -//│ deforest > call mk@result @ mk2d@mk2d.mk@mk -> UnsafeEta -//│ deforest > call mk@result @ mk2d@mk2d.mk@mk -> UnsafeEta -//│ deforest > call mk@result @ mk@mk -> UnsafeEta -//│ deforest > call sum@result @ -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta -//│ deforest > call sum@result @ sum@sum -> UnsafeEta +//│ deforest > function append⁰#0 @ append² -> UnsafeEta +//│ deforest > function append⁰#0 @ flatten².append¹ -> UnsafeEta +//│ deforest > function append⁰#0 @ flatten⁰.append¹ -> UnsafeEta +//│ deforest > function flatten¹#0 @ flatten² -> UnsafeEta +//│ deforest > function flatten¹#0 @ flatten⁰ -> UnsafeEta +//│ deforest > function mk2d¹#0 @ mk2d² -> UnsafeEta +//│ deforest > function mk2d¹#0 @ mk2d⁰ -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk2d².mk¹ -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk2d⁰.mk¹ -> UnsafeEta +//│ deforest > function mk⁰#0 @ mk² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum² -> UnsafeEta +//│ deforest > function sum⁰#0 @ sum¹ -> UnsafeEta +//│ deforest > call +⁰@result⁴ @ sum² -> Pure +//│ deforest > call +⁰@result⁴ @ sum¹ -> Pure +//│ deforest > call -⁰@result¹⁰ @ mk2d² -> Pure +//│ deforest > call -⁰@result¹⁰ @ mk2d⁰ -> Pure +//│ deforest > call -⁰@result⁷ @ mk2d².mk¹ -> Pure +//│ deforest > call -⁰@result⁷ @ mk2d⁰.mk¹ -> Pure +//│ deforest > call -⁰@result⁷ @ mk² -> Pure +//│ deforest > call >⁰@result⁵ @ mk2d² -> Pure +//│ deforest > call >⁰@result⁵ @ mk2d⁰ -> Pure +//│ deforest > call >⁰@result⁸ @ mk2d².mk¹ -> Pure +//│ deforest > call >⁰@result⁸ @ mk2d⁰.mk¹ -> Pure +//│ deforest > call >⁰@result⁸ @ mk² -> Pure +//│ deforest > call append⁰@result² @ flatten² -> UnsafeEta +//│ deforest > call append⁰@result² @ flatten⁰ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ append² -> UnsafeEta +//│ deforest > call append⁰@result¹ @ flatten².append¹ -> UnsafeEta +//│ deforest > call append⁰@result¹ @ flatten⁰.append¹ -> UnsafeEta +//│ deforest > call flatten¹@result¹³ @ -> UnsafeEta +//│ deforest > call flatten¹@result⁰ @ flatten² -> UnsafeEta +//│ deforest > call flatten¹@result⁰ @ flatten⁰ -> UnsafeEta +//│ deforest > call id@result¹⁴ @ -> UnsafeEta +//│ deforest > call mk2d¹@result¹¹ @ mk2d² -> UnsafeEta +//│ deforest > call mk2d¹@result¹¹ @ mk2d⁰ -> UnsafeEta +//│ deforest > call mk2d¹@result¹⁵ @ -> UnsafeEta +//│ deforest > call mk⁰@result⁶ @ mk2d².mk¹ -> UnsafeEta +//│ deforest > call mk⁰@result⁶ @ mk2d⁰.mk¹ -> UnsafeEta +//│ deforest > call mk⁰@result⁶ @ mk² -> UnsafeEta +//│ deforest > call mk⁰@result⁹ @ mk2d² -> UnsafeEta +//│ deforest > call mk⁰@result⁹ @ mk2d⁰ -> UnsafeEta +//│ deforest > call sum⁰@result³ @ sum² -> UnsafeEta +//│ deforest > call sum⁰@result³ @ sum¹ -> UnsafeEta +//│ deforest > call sum⁰@result¹² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -1091,18 +1091,18 @@ fun rev(a, ys) = if ys is Nil then a count(0, rev(Nil, 1 :: 2 :: Nil)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function count#0 @ count@count -> UnsafeEta -//│ deforest > function count#0 @ count@count -> UnsafeEta -//│ deforest > function rev#0 @ rev@rev -> UnsafeEta -//│ deforest > function rev#0 @ rev@rev -> UnsafeEta -//│ deforest > call +@result @ count@count -> Pure -//│ deforest > call +@result @ count@count -> Pure -//│ deforest > call count@result @ -> UnsafeEta -//│ deforest > call count@result @ count@count -> UnsafeEta -//│ deforest > call count@result @ count@count -> UnsafeEta -//│ deforest > call rev@result @ -> UnsafeEta -//│ deforest > call rev@result @ rev@rev -> UnsafeEta -//│ deforest > call rev@result @ rev@rev -> UnsafeEta +//│ deforest > function count⁰#0 @ count² -> UnsafeEta +//│ deforest > function count⁰#0 @ count¹ -> UnsafeEta +//│ deforest > function rev⁰#0 @ rev² -> UnsafeEta +//│ deforest > function rev⁰#0 @ rev¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ count² -> Pure +//│ deforest > call +⁰@result¹ @ count¹ -> Pure +//│ deforest > call count⁰@result² @ count² -> UnsafeEta +//│ deforest > call count⁰@result² @ count¹ -> UnsafeEta +//│ deforest > call count⁰@result³ @ -> UnsafeEta +//│ deforest > call rev⁰@result⁰ @ rev² -> UnsafeEta +//│ deforest > call rev⁰@result⁰ @ rev¹ -> UnsafeEta +//│ deforest > call rev⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -1134,11 +1134,11 @@ fun last(ls) = if ls is let p = 1 :: 2 :: Nil last(p) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function last#0 @ last@last -> UnsafeEta -//│ deforest > function last#0 @ last@last -> UnsafeEta -//│ deforest > call last@result @ -> UnsafeEta -//│ deforest > call last@result @ last@last -> UnsafeEta -//│ deforest > call last@result @ last@last -> UnsafeEta +//│ deforest > function last⁰#0 @ last² -> UnsafeEta +//│ deforest > function last⁰#0 @ last¹ -> UnsafeEta +//│ deforest > call last⁰@result¹ @ -> UnsafeEta +//│ deforest > call last⁰@result⁰ @ last² -> UnsafeEta +//│ deforest > call last⁰@result⁰ @ last¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1153,15 +1153,15 @@ fun map(f, xs_map) = if xs_map is x :: xs then f(x) :: map(f, xs) map(x => if x is A then 1 else 0, A :: B :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > call f@result @ map@map -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function map⁰#0 @ map² -> UnsafeEta +//│ deforest > function map⁰#0 @ map¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ map² -> Pure +//│ deforest > call f⁰@result⁰ @ map¹ -> UnsafeEta +//│ deforest > call map⁰@result² @ -> UnsafeEta +//│ deforest > call map⁰@result¹ @ map² -> UnsafeEta +//│ deforest > call map⁰@result¹ @ map¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(A⁰, tmp²⁷) -> @@ -1193,13 +1193,13 @@ fun c(x) = if x is L then L c(T(A, T(B, L, L), T(A, L, L))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call c@result @ c@c -> UnsafeEta -//│ deforest > call c@result @ c@c -> UnsafeEta -//│ deforest > call c@result @ c@c -> UnsafeEta -//│ deforest > call c@result @ c@c -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call c⁰@result² @ -> UnsafeEta +//│ deforest > call c⁰@result¹ @ c² -> UnsafeEta +//│ deforest > call c⁰@result¹ @ c¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ c² -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ c¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > T⁰(A⁰, tmp²⁸, tmp²⁹) -> @@ -1243,15 +1243,15 @@ fun max(ms, m) = if ms is Nil then m max(3 :: 2 :: 4 :: 1 :: 0 :: Nil, 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function max#0 @ max@max -> UnsafeEta -//│ deforest > function max#0 @ max@max -> UnsafeEta -//│ deforest > call >@result @ max@max -> Pure -//│ deforest > call >@result @ max@max -> Pure -//│ deforest > call max@result @ -> UnsafeEta -//│ deforest > call max@result @ max@max -> UnsafeEta -//│ deforest > call max@result @ max@max -> UnsafeEta -//│ deforest > call max@result @ max@max -> UnsafeEta -//│ deforest > call max@result @ max@max -> UnsafeEta +//│ deforest > function max⁰#0 @ max² -> UnsafeEta +//│ deforest > function max⁰#0 @ max¹ -> UnsafeEta +//│ deforest > call >⁰@result⁰ @ max² -> Pure +//│ deforest > call >⁰@result⁰ @ max¹ -> Pure +//│ deforest > call max⁰@result² @ max² -> UnsafeEta +//│ deforest > call max⁰@result² @ max¹ -> UnsafeEta +//│ deforest > call max⁰@result³ @ -> UnsafeEta +//│ deforest > call max⁰@result¹ @ max² -> UnsafeEta +//│ deforest > call max⁰@result¹ @ max¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(3, tmp³⁰) -> @@ -1296,44 +1296,44 @@ fun last(ls_last) = fun lastFilter(ls, f) = last(filter(ls, f)) lastFilter(id(1 :: 2 :: 3 :: 4 :: 5 :: Nil), x => (x % 2 == 0)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function filter#0 @ filter@filter -> UnsafeEta -//│ deforest > function filter#0 @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > function filter#0 @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > function go#0 @ last@last -> UnsafeEta -//│ deforest > function go#0 @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > function go#0 @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta -//│ deforest > function lambda#0 @ lambda@lambda -> UnsafeEta -//│ deforest > function last#0 @ last@last -> UnsafeEta -//│ deforest > function last#0 @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > function last#0 @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > function lastFilter#0 @ lastFilter@lastFilter -> UnsafeEta -//│ deforest > function lastFilter#0 @ lastFilter@lastFilter -> UnsafeEta -//│ deforest > call %@result @ lambda@lambda -> Pure -//│ deforest > call %@result @ lambda@lambda -> Pure -//│ deforest > call equals@result @ lambda@lambda -> UnsafeEta -//│ deforest > call equals@result @ lambda@lambda -> UnsafeEta -//│ deforest > call f@result @ filter@filter -> UnsafeEta -//│ deforest > call f@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > call f@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > call filter@result @ filter@filter -> UnsafeEta -//│ deforest > call filter@result @ filter@filter -> UnsafeEta -//│ deforest > call filter@result @ lastFilter@lastFilter -> UnsafeEta -//│ deforest > call filter@result @ lastFilter@lastFilter -> UnsafeEta -//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > call filter@result @ lastFilter@lastFilter.filter@filter -> UnsafeEta -//│ deforest > call go@result @ last@last -> UnsafeEta -//│ deforest > call go@result @ last@last -> UnsafeEta -//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > call go@result @ lastFilter@lastFilter.last@last -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call last@result @ lastFilter@lastFilter -> UnsafeEta -//│ deforest > call last@result @ lastFilter@lastFilter -> UnsafeEta -//│ deforest > call lastFilter@result @ -> UnsafeEta +//│ deforest > function filter⁰#0 @ filter² -> UnsafeEta +//│ deforest > function filter⁰#0 @ lastFilter².filter¹ -> UnsafeEta +//│ deforest > function filter⁰#0 @ lastFilter⁰.filter¹ -> UnsafeEta +//│ deforest > function go⁰#0 @ lastFilter².last¹ -> UnsafeEta +//│ deforest > function go⁰#0 @ lastFilter⁰.last¹ -> UnsafeEta +//│ deforest > function go⁰#0 @ last² -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda¹ -> UnsafeEta +//│ deforest > function lastFilter¹#0 @ lastFilter² -> UnsafeEta +//│ deforest > function lastFilter¹#0 @ lastFilter⁰ -> UnsafeEta +//│ deforest > function last⁰#0 @ lastFilter².last¹ -> UnsafeEta +//│ deforest > function last⁰#0 @ lastFilter⁰.last¹ -> UnsafeEta +//│ deforest > function last⁰#0 @ last² -> UnsafeEta +//│ deforest > call %⁰@result⁰ @ lambda² -> Pure +//│ deforest > call %⁰@result⁰ @ lambda¹ -> Pure +//│ deforest > call equals@result¹ @ lambda² -> UnsafeEta +//│ deforest > call equals@result¹ @ lambda¹ -> UnsafeEta +//│ deforest > call filter⁰@result² @ filter² -> UnsafeEta +//│ deforest > call filter⁰@result² @ lastFilter².filter¹ -> UnsafeEta +//│ deforest > call filter⁰@result² @ lastFilter⁰.filter¹ -> UnsafeEta +//│ deforest > call filter⁰@result³ @ filter² -> UnsafeEta +//│ deforest > call filter⁰@result³ @ lastFilter².filter¹ -> UnsafeEta +//│ deforest > call filter⁰@result³ @ lastFilter⁰.filter¹ -> UnsafeEta +//│ deforest > call filter⁰@result⁵ @ lastFilter² -> UnsafeEta +//│ deforest > call filter⁰@result⁵ @ lastFilter⁰ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ filter² -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ lastFilter².filter¹ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ lastFilter⁰.filter¹ -> UnsafeEta +//│ deforest > call go⁰@result⁶ @ lastFilter².last¹ -> UnsafeEta +//│ deforest > call go⁰@result⁶ @ lastFilter⁰.last¹ -> UnsafeEta +//│ deforest > call go⁰@result⁶ @ last² -> UnsafeEta +//│ deforest > call go⁰@result⁷ @ lastFilter².last¹ -> UnsafeEta +//│ deforest > call go⁰@result⁷ @ lastFilter⁰.last¹ -> UnsafeEta +//│ deforest > call go⁰@result⁷ @ last² -> UnsafeEta +//│ deforest > call id@result¹⁰ @ -> UnsafeEta +//│ deforest > call lastFilter¹@result⁹ @ -> UnsafeEta +//│ deforest > call last⁰@result⁸ @ lastFilter² -> UnsafeEta +//│ deforest > call last⁰@result⁸ @ lastFilter⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1345,30 +1345,30 @@ fun g() = f() fun f() = g() + g() [f, g] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function f¹#0 @ g² -> Pure +//│ deforest > function f¹#0 @ g¹ -> Pure +//│ deforest > function g⁰#0 @ f² -> Pure +//│ deforest > function g⁰#0 @ f⁰ -> Pure +//│ deforest > function g⁰#0 @ g² -> Pure +//│ deforest > function g⁰#0 @ g¹ -> Pure +//│ deforest > call +⁰@result³ @ f² -> Pure +//│ deforest > call +⁰@result³ @ f⁰ -> Pure +//│ deforest > call +⁰@result³ @ g² -> Pure +//│ deforest > call +⁰@result³ @ g¹ -> Pure +//│ deforest > call f¹@result⁰ @ f² -> Pure +//│ deforest > call f¹@result⁰ @ f⁰ -> Pure +//│ deforest > call f¹@result⁰ @ g² -> Pure +//│ deforest > call f¹@result⁰ @ g¹ -> Pure +//│ deforest > call g⁰@result² @ f² -> Pure +//│ deforest > call g⁰@result² @ f⁰ -> Pure +//│ deforest > call g⁰@result² @ g² -> Pure +//│ deforest > call g⁰@result² @ g¹ -> Pure +//│ deforest > call g⁰@result¹ @ f² -> Pure +//│ deforest > call g⁰@result¹ @ f⁰ -> Pure +//│ deforest > call g⁰@result¹ @ g² -> Pure +//│ deforest > call g⁰@result¹ @ g¹ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1383,86 +1383,86 @@ fun g() = f() fun f() = h1() + h2() [h1, h2, g, f] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ h1@h1 -> Pure -//│ deforest > function f#0 @ h1@h1 -> Pure -//│ deforest > function f#0 @ h2@h2 -> Pure -//│ deforest > function f#0 @ h2@h2 -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ h1@h1 -> Pure -//│ deforest > function g#0 @ h1@h1 -> Pure -//│ deforest > function g#0 @ h2@h2 -> Pure -//│ deforest > function g#0 @ h2@h2 -> Pure -//│ deforest > function h1#0 @ f@f -> Pure -//│ deforest > function h1#0 @ f@f -> Pure -//│ deforest > function h1#0 @ g@g -> Pure -//│ deforest > function h1#0 @ g@g -> Pure -//│ deforest > function h1#0 @ h1@h1 -> Pure -//│ deforest > function h1#0 @ h1@h1 -> Pure -//│ deforest > function h1#0 @ h2@h2 -> Pure -//│ deforest > function h1#0 @ h2@h2 -> Pure -//│ deforest > function h2#0 @ f@f -> Pure -//│ deforest > function h2#0 @ f@f -> Pure -//│ deforest > function h2#0 @ g@g -> Pure -//│ deforest > function h2#0 @ g@g -> Pure -//│ deforest > function h2#0 @ h1@h1 -> Pure -//│ deforest > function h2#0 @ h1@h1 -> Pure -//│ deforest > function h2#0 @ h2@h2 -> Pure -//│ deforest > function h2#0 @ h2@h2 -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ h1@h1 -> Pure -//│ deforest > call f@result @ h1@h1 -> Pure -//│ deforest > call f@result @ h2@h2 -> Pure -//│ deforest > call f@result @ h2@h2 -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function f¹#0 @ g² -> Pure +//│ deforest > function f¹#0 @ g¹ -> Pure +//│ deforest > function f¹#0 @ h1² -> Pure +//│ deforest > function f¹#0 @ h1¹ -> Pure +//│ deforest > function f¹#0 @ h2² -> Pure +//│ deforest > function f¹#0 @ h2¹ -> Pure +//│ deforest > function g⁰#0 @ f² -> Pure +//│ deforest > function g⁰#0 @ f⁰ -> Pure +//│ deforest > function g⁰#0 @ g² -> Pure +//│ deforest > function g⁰#0 @ g¹ -> Pure +//│ deforest > function g⁰#0 @ h1² -> Pure +//│ deforest > function g⁰#0 @ h1¹ -> Pure +//│ deforest > function g⁰#0 @ h2² -> Pure +//│ deforest > function g⁰#0 @ h2¹ -> Pure +//│ deforest > function h1⁰#0 @ f² -> Pure +//│ deforest > function h1⁰#0 @ f⁰ -> Pure +//│ deforest > function h1⁰#0 @ g² -> Pure +//│ deforest > function h1⁰#0 @ g¹ -> Pure +//│ deforest > function h1⁰#0 @ h1² -> Pure +//│ deforest > function h1⁰#0 @ h1¹ -> Pure +//│ deforest > function h1⁰#0 @ h2² -> Pure +//│ deforest > function h1⁰#0 @ h2¹ -> Pure +//│ deforest > function h2⁰#0 @ f² -> Pure +//│ deforest > function h2⁰#0 @ f⁰ -> Pure +//│ deforest > function h2⁰#0 @ g² -> Pure +//│ deforest > function h2⁰#0 @ g¹ -> Pure +//│ deforest > function h2⁰#0 @ h1² -> Pure +//│ deforest > function h2⁰#0 @ h1¹ -> Pure +//│ deforest > function h2⁰#0 @ h2² -> Pure +//│ deforest > function h2⁰#0 @ h2¹ -> Pure +//│ deforest > call +⁰@result⁴ @ f² -> Pure +//│ deforest > call +⁰@result⁴ @ f⁰ -> Pure +//│ deforest > call +⁰@result⁴ @ g² -> Pure +//│ deforest > call +⁰@result⁴ @ g¹ -> Pure +//│ deforest > call +⁰@result⁴ @ h1² -> Pure +//│ deforest > call +⁰@result⁴ @ h1¹ -> Pure +//│ deforest > call +⁰@result⁴ @ h2² -> Pure +//│ deforest > call +⁰@result⁴ @ h2¹ -> Pure +//│ deforest > call f¹@result¹ @ f² -> Pure +//│ deforest > call f¹@result¹ @ f⁰ -> Pure +//│ deforest > call f¹@result¹ @ g² -> Pure +//│ deforest > call f¹@result¹ @ g¹ -> Pure +//│ deforest > call f¹@result¹ @ h1² -> Pure +//│ deforest > call f¹@result¹ @ h1¹ -> Pure +//│ deforest > call f¹@result¹ @ h2² -> Pure +//│ deforest > call f¹@result¹ @ h2¹ -> Pure +//│ deforest > call g⁰@result⁰ @ f² -> Pure +//│ deforest > call g⁰@result⁰ @ f⁰ -> Pure +//│ deforest > call g⁰@result⁰ @ g² -> Pure +//│ deforest > call g⁰@result⁰ @ g¹ -> Pure +//│ deforest > call g⁰@result⁰ @ h1² -> Pure +//│ deforest > call g⁰@result⁰ @ h1¹ -> Pure +//│ deforest > call g⁰@result⁰ @ h2² -> Pure +//│ deforest > call g⁰@result⁰ @ h2¹ -> Pure +//│ deforest > call g⁰@result⁵ @ f² -> Pure +//│ deforest > call g⁰@result⁵ @ f⁰ -> Pure +//│ deforest > call g⁰@result⁵ @ g² -> Pure +//│ deforest > call g⁰@result⁵ @ g¹ -> Pure +//│ deforest > call g⁰@result⁵ @ h1² -> Pure +//│ deforest > call g⁰@result⁵ @ h1¹ -> Pure +//│ deforest > call g⁰@result⁵ @ h2² -> Pure +//│ deforest > call g⁰@result⁵ @ h2¹ -> Pure +//│ deforest > call h1⁰@result² @ f² -> Pure +//│ deforest > call h1⁰@result² @ f⁰ -> Pure +//│ deforest > call h1⁰@result² @ g² -> Pure +//│ deforest > call h1⁰@result² @ g¹ -> Pure +//│ deforest > call h1⁰@result² @ h1² -> Pure +//│ deforest > call h1⁰@result² @ h1¹ -> Pure +//│ deforest > call h1⁰@result² @ h2² -> Pure +//│ deforest > call h1⁰@result² @ h2¹ -> Pure +//│ deforest > call h2⁰@result³ @ f² -> Pure +//│ deforest > call h2⁰@result³ @ f⁰ -> Pure +//│ deforest > call h2⁰@result³ @ g² -> Pure +//│ deforest > call h2⁰@result³ @ g¹ -> Pure +//│ deforest > call h2⁰@result³ @ h1² -> Pure +//│ deforest > call h2⁰@result³ @ h1¹ -> Pure +//│ deforest > call h2⁰@result³ @ h2² -> Pure +//│ deforest > call h2⁰@result³ @ h2¹ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1478,102 +1478,102 @@ fun g() = f() fun f() = h1() + h2() [h1, h2, g, f] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ h1@h1 -> Pure -//│ deforest > function f#0 @ h1@h1 -> Pure -//│ deforest > function f#0 @ h2@h2 -> Pure -//│ deforest > function f#0 @ h2@h2 -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ h1@h1 -> Pure -//│ deforest > function g#0 @ h1@h1 -> Pure -//│ deforest > function g#0 @ h2@h2 -> Pure -//│ deforest > function g#0 @ h2@h2 -> Pure -//│ deforest > function h1#0 @ f@f -> Pure -//│ deforest > function h1#0 @ f@f -> Pure -//│ deforest > function h1#0 @ g@g -> Pure -//│ deforest > function h1#0 @ g@g -> Pure -//│ deforest > function h1#0 @ h1@h1 -> Pure -//│ deforest > function h1#0 @ h1@h1 -> Pure -//│ deforest > function h1#0 @ h2@h2 -> Pure -//│ deforest > function h1#0 @ h2@h2 -> Pure -//│ deforest > function h2#0 @ f@f -> Pure -//│ deforest > function h2#0 @ f@f -> Pure -//│ deforest > function h2#0 @ g@g -> Pure -//│ deforest > function h2#0 @ g@g -> Pure -//│ deforest > function h2#0 @ h1@h1 -> Pure -//│ deforest > function h2#0 @ h1@h1 -> Pure -//│ deforest > function h2#0 @ h2@h2 -> Pure -//│ deforest > function h2#0 @ h2@h2 -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ h1@h1 -> Pure -//│ deforest > call f@result @ h1@h1 -> Pure -//│ deforest > call f@result @ h2@h2 -> Pure -//│ deforest > call f@result @ h2@h2 -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function f¹#0 @ g² -> Pure +//│ deforest > function f¹#0 @ g¹ -> Pure +//│ deforest > function f¹#0 @ h1² -> Pure +//│ deforest > function f¹#0 @ h1¹ -> Pure +//│ deforest > function f¹#0 @ h2² -> Pure +//│ deforest > function f¹#0 @ h2¹ -> Pure +//│ deforest > function g⁰#0 @ f² -> Pure +//│ deforest > function g⁰#0 @ f⁰ -> Pure +//│ deforest > function g⁰#0 @ g² -> Pure +//│ deforest > function g⁰#0 @ g¹ -> Pure +//│ deforest > function g⁰#0 @ h1² -> Pure +//│ deforest > function g⁰#0 @ h1¹ -> Pure +//│ deforest > function g⁰#0 @ h2² -> Pure +//│ deforest > function g⁰#0 @ h2¹ -> Pure +//│ deforest > function h1⁰#0 @ f² -> Pure +//│ deforest > function h1⁰#0 @ f⁰ -> Pure +//│ deforest > function h1⁰#0 @ g² -> Pure +//│ deforest > function h1⁰#0 @ g¹ -> Pure +//│ deforest > function h1⁰#0 @ h1² -> Pure +//│ deforest > function h1⁰#0 @ h1¹ -> Pure +//│ deforest > function h1⁰#0 @ h2² -> Pure +//│ deforest > function h1⁰#0 @ h2¹ -> Pure +//│ deforest > function h2⁰#0 @ f² -> Pure +//│ deforest > function h2⁰#0 @ f⁰ -> Pure +//│ deforest > function h2⁰#0 @ g² -> Pure +//│ deforest > function h2⁰#0 @ g¹ -> Pure +//│ deforest > function h2⁰#0 @ h1² -> Pure +//│ deforest > function h2⁰#0 @ h1¹ -> Pure +//│ deforest > function h2⁰#0 @ h2² -> Pure +//│ deforest > function h2⁰#0 @ h2¹ -> Pure +//│ deforest > call +⁰@result⁴ @ f² -> Pure +//│ deforest > call +⁰@result⁴ @ f⁰ -> Pure +//│ deforest > call +⁰@result⁴ @ g² -> Pure +//│ deforest > call +⁰@result⁴ @ g¹ -> Pure +//│ deforest > call +⁰@result⁴ @ h1² -> Pure +//│ deforest > call +⁰@result⁴ @ h1¹ -> Pure +//│ deforest > call +⁰@result⁴ @ h2² -> Pure +//│ deforest > call +⁰@result⁴ @ h2¹ -> Pure +//│ deforest > call +⁰@result⁷ @ f² -> Pure +//│ deforest > call +⁰@result⁷ @ f⁰ -> Pure +//│ deforest > call +⁰@result⁷ @ g² -> Pure +//│ deforest > call +⁰@result⁷ @ g¹ -> Pure +//│ deforest > call +⁰@result⁷ @ h1² -> Pure +//│ deforest > call +⁰@result⁷ @ h1¹ -> Pure +//│ deforest > call +⁰@result⁷ @ h2² -> Pure +//│ deforest > call +⁰@result⁷ @ h2¹ -> Pure +//│ deforest > call f¹@result¹ @ f² -> Pure +//│ deforest > call f¹@result¹ @ f⁰ -> Pure +//│ deforest > call f¹@result¹ @ g² -> Pure +//│ deforest > call f¹@result¹ @ g¹ -> Pure +//│ deforest > call f¹@result¹ @ h1² -> Pure +//│ deforest > call f¹@result¹ @ h1¹ -> Pure +//│ deforest > call f¹@result¹ @ h2² -> Pure +//│ deforest > call f¹@result¹ @ h2¹ -> Pure +//│ deforest > call g⁰@result⁰ @ f² -> Pure +//│ deforest > call g⁰@result⁰ @ f⁰ -> Pure +//│ deforest > call g⁰@result⁰ @ g² -> Pure +//│ deforest > call g⁰@result⁰ @ g¹ -> Pure +//│ deforest > call g⁰@result⁰ @ h1² -> Pure +//│ deforest > call g⁰@result⁰ @ h1¹ -> Pure +//│ deforest > call g⁰@result⁰ @ h2² -> Pure +//│ deforest > call g⁰@result⁰ @ h2¹ -> Pure +//│ deforest > call g⁰@result⁵ @ f² -> Pure +//│ deforest > call g⁰@result⁵ @ f⁰ -> Pure +//│ deforest > call g⁰@result⁵ @ g² -> Pure +//│ deforest > call g⁰@result⁵ @ g¹ -> Pure +//│ deforest > call g⁰@result⁵ @ h1² -> Pure +//│ deforest > call g⁰@result⁵ @ h1¹ -> Pure +//│ deforest > call g⁰@result⁵ @ h2² -> Pure +//│ deforest > call g⁰@result⁵ @ h2¹ -> Pure +//│ deforest > call h1⁰@result² @ f² -> Pure +//│ deforest > call h1⁰@result² @ f⁰ -> Pure +//│ deforest > call h1⁰@result² @ g² -> Pure +//│ deforest > call h1⁰@result² @ g¹ -> Pure +//│ deforest > call h1⁰@result² @ h1² -> Pure +//│ deforest > call h1⁰@result² @ h1¹ -> Pure +//│ deforest > call h1⁰@result² @ h2² -> Pure +//│ deforest > call h1⁰@result² @ h2¹ -> Pure +//│ deforest > call h1⁰@result⁶ @ f² -> Pure +//│ deforest > call h1⁰@result⁶ @ f⁰ -> Pure +//│ deforest > call h1⁰@result⁶ @ g² -> Pure +//│ deforest > call h1⁰@result⁶ @ g¹ -> Pure +//│ deforest > call h1⁰@result⁶ @ h1² -> Pure +//│ deforest > call h1⁰@result⁶ @ h1¹ -> Pure +//│ deforest > call h1⁰@result⁶ @ h2² -> Pure +//│ deforest > call h1⁰@result⁶ @ h2¹ -> Pure +//│ deforest > call h2⁰@result³ @ f² -> Pure +//│ deforest > call h2⁰@result³ @ f⁰ -> Pure +//│ deforest > call h2⁰@result³ @ g² -> Pure +//│ deforest > call h2⁰@result³ @ g¹ -> Pure +//│ deforest > call h2⁰@result³ @ h1² -> Pure +//│ deforest > call h2⁰@result³ @ h1¹ -> Pure +//│ deforest > call h2⁰@result³ @ h2² -> Pure +//│ deforest > call h2⁰@result³ @ h2¹ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1596,76 +1596,76 @@ fun g() = if else 0 main //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ h@h -> Pure -//│ deforest > function f#0 @ main@main -> Pure -//│ deforest > function f#0 @ main@main -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ h@h -> Pure -//│ deforest > function g#0 @ main@main -> Pure -//│ deforest > function g#0 @ main@main -> Pure -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function h#0 @ g@g -> Pure -//│ deforest > function h#0 @ h@h -> Pure -//│ deforest > function h#0 @ main@main -> Pure -//│ deforest > function h#0 @ main@main -> Pure -//│ deforest > function main#0 @ f@f -> Pure -//│ deforest > function main#0 @ g@g -> Pure -//│ deforest > function main#0 @ h@h -> Pure -//│ deforest > function main#0 @ main@main -> Pure -//│ deforest > function main#0 @ main@main -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ h@h -> Pure -//│ deforest > call +@result @ h@h -> Pure -//│ deforest > call +@result @ h@h -> Pure -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call +@result @ main@main -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ h@h -> Pure -//│ deforest > call f@result @ h@h -> Pure -//│ deforest > call f@result @ main@main -> Pure -//│ deforest > call f@result @ main@main -> Pure -//│ deforest > call f@result @ main@main -> Pure -//│ deforest > call f@result @ main@main -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ h@h -> Pure -//│ deforest > call g@result @ main@main -> Pure -//│ deforest > call g@result @ main@main -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ g@g -> Pure -//│ deforest > call h@result @ g@g -> Pure -//│ deforest > call h@result @ h@h -> Pure -//│ deforest > call h@result @ h@h -> Pure -//│ deforest > call h@result @ main@main -> Pure -//│ deforest > call h@result @ main@main -> Pure -//│ deforest > call h@result @ main@main -> Pure -//│ deforest > call h@result @ main@main -> Pure -//│ deforest > call main@result @ f@f -> Pure -//│ deforest > call main@result @ f@f -> Pure -//│ deforest > call main@result @ g@g -> Pure -//│ deforest > call main@result @ g@g -> Pure -//│ deforest > call main@result @ h@h -> Pure -//│ deforest > call main@result @ h@h -> Pure -//│ deforest > call main@result @ main@main -> Pure -//│ deforest > call main@result @ main@main -> Pure -//│ deforest > call main@result @ main@main -> Pure -//│ deforest > call main@result @ main@main -> Pure +//│ deforest > function f⁰#0 @ f¹ -> Pure +//│ deforest > function f⁰#0 @ g⁰ -> Pure +//│ deforest > function f⁰#0 @ h³ -> Pure +//│ deforest > function f⁰#0 @ main² -> Pure +//│ deforest > function f⁰#0 @ main¹ -> Pure +//│ deforest > function g¹#0 @ f¹ -> Pure +//│ deforest > function g¹#0 @ g⁰ -> Pure +//│ deforest > function g¹#0 @ h³ -> Pure +//│ deforest > function g¹#0 @ main² -> Pure +//│ deforest > function g¹#0 @ main¹ -> Pure +//│ deforest > function h²#0 @ f¹ -> Pure +//│ deforest > function h²#0 @ g⁰ -> Pure +//│ deforest > function h²#0 @ h³ -> Pure +//│ deforest > function h²#0 @ main² -> Pure +//│ deforest > function h²#0 @ main¹ -> Pure +//│ deforest > function main⁰#0 @ f¹ -> Pure +//│ deforest > function main⁰#0 @ g⁰ -> Pure +//│ deforest > function main⁰#0 @ h³ -> Pure +//│ deforest > function main⁰#0 @ main² -> Pure +//│ deforest > function main⁰#0 @ main¹ -> Pure +//│ deforest > call +⁰@result² @ f¹ -> Pure +//│ deforest > call +⁰@result² @ g⁰ -> Pure +//│ deforest > call +⁰@result² @ h³ -> Pure +//│ deforest > call +⁰@result² @ main² -> Pure +//│ deforest > call +⁰@result² @ main¹ -> Pure +//│ deforest > call +⁰@result⁵ @ f¹ -> Pure +//│ deforest > call +⁰@result⁵ @ g⁰ -> Pure +//│ deforest > call +⁰@result⁵ @ h³ -> Pure +//│ deforest > call +⁰@result⁵ @ main² -> Pure +//│ deforest > call +⁰@result⁵ @ main¹ -> Pure +//│ deforest > call +⁰@result⁸ @ f¹ -> Pure +//│ deforest > call +⁰@result⁸ @ g⁰ -> Pure +//│ deforest > call +⁰@result⁸ @ h³ -> Pure +//│ deforest > call +⁰@result⁸ @ main² -> Pure +//│ deforest > call +⁰@result⁸ @ main¹ -> Pure +//│ deforest > call f⁰@result⁰ @ f¹ -> Pure +//│ deforest > call f⁰@result⁰ @ g⁰ -> Pure +//│ deforest > call f⁰@result⁰ @ h³ -> Pure +//│ deforest > call f⁰@result⁰ @ main² -> Pure +//│ deforest > call f⁰@result⁰ @ main¹ -> Pure +//│ deforest > call f⁰@result⁶ @ f¹ -> Pure +//│ deforest > call f⁰@result⁶ @ g⁰ -> Pure +//│ deforest > call f⁰@result⁶ @ h³ -> Pure +//│ deforest > call f⁰@result⁶ @ main² -> Pure +//│ deforest > call f⁰@result⁶ @ main¹ -> Pure +//│ deforest > call g¹@result¹ @ f¹ -> Pure +//│ deforest > call g¹@result¹ @ g⁰ -> Pure +//│ deforest > call g¹@result¹ @ h³ -> Pure +//│ deforest > call g¹@result¹ @ main² -> Pure +//│ deforest > call g¹@result¹ @ main¹ -> Pure +//│ deforest > call h²@result³ @ f¹ -> Pure +//│ deforest > call h²@result³ @ g⁰ -> Pure +//│ deforest > call h²@result³ @ h³ -> Pure +//│ deforest > call h²@result³ @ main² -> Pure +//│ deforest > call h²@result³ @ main¹ -> Pure +//│ deforest > call h²@result⁹ @ f¹ -> Pure +//│ deforest > call h²@result⁹ @ g⁰ -> Pure +//│ deforest > call h²@result⁹ @ h³ -> Pure +//│ deforest > call h²@result⁹ @ main² -> Pure +//│ deforest > call h²@result⁹ @ main¹ -> Pure +//│ deforest > call main⁰@result⁴ @ f¹ -> Pure +//│ deforest > call main⁰@result⁴ @ g⁰ -> Pure +//│ deforest > call main⁰@result⁴ @ h³ -> Pure +//│ deforest > call main⁰@result⁴ @ main² -> Pure +//│ deforest > call main⁰@result⁴ @ main¹ -> Pure +//│ deforest > call main⁰@result⁷ @ f¹ -> Pure +//│ deforest > call main⁰@result⁷ @ g⁰ -> Pure +//│ deforest > call main⁰@result⁷ @ h³ -> Pure +//│ deforest > call main⁰@result⁷ @ main² -> Pure +//│ deforest > call main⁰@result⁷ @ main¹ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1685,78 +1685,78 @@ fun h2() = g2() fun g2() = f() f //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ g1@g1 -> UnsafeEta -//│ deforest > function f#0 @ g2@g2 -> UnsafeEta -//│ deforest > function f#0 @ h1@h1 -> UnsafeEta -//│ deforest > function f#0 @ h2@h2 -> UnsafeEta -//│ deforest > function g1#0 @ f@f -> UnsafeEta -//│ deforest > function g1#0 @ f@f -> UnsafeEta -//│ deforest > function g1#0 @ g1@g1 -> UnsafeEta -//│ deforest > function g1#0 @ g2@g2 -> UnsafeEta -//│ deforest > function g1#0 @ h1@h1 -> UnsafeEta -//│ deforest > function g1#0 @ h2@h2 -> UnsafeEta -//│ deforest > function g2#0 @ f@f -> UnsafeEta -//│ deforest > function g2#0 @ f@f -> UnsafeEta -//│ deforest > function g2#0 @ g1@g1 -> UnsafeEta -//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta -//│ deforest > function g2#0 @ h1@h1 -> UnsafeEta -//│ deforest > function g2#0 @ h2@h2 -> UnsafeEta -//│ deforest > function h1#0 @ f@f -> UnsafeEta -//│ deforest > function h1#0 @ f@f -> UnsafeEta -//│ deforest > function h1#0 @ g1@g1 -> UnsafeEta -//│ deforest > function h1#0 @ g2@g2 -> UnsafeEta -//│ deforest > function h1#0 @ h1@h1 -> UnsafeEta -//│ deforest > function h1#0 @ h2@h2 -> UnsafeEta -//│ deforest > function h2#0 @ f@f -> UnsafeEta -//│ deforest > function h2#0 @ f@f -> UnsafeEta -//│ deforest > function h2#0 @ g1@g1 -> UnsafeEta -//│ deforest > function h2#0 @ g2@g2 -> UnsafeEta -//│ deforest > function h2#0 @ h1@h1 -> UnsafeEta -//│ deforest > function h2#0 @ h2@h2 -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ g1@g1 -> Pure -//│ deforest > call +@result @ g2@g2 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ g1@g1 -> UnsafeEta -//│ deforest > call f@result @ g1@g1 -> UnsafeEta -//│ deforest > call f@result @ g2@g2 -> UnsafeEta -//│ deforest > call f@result @ g2@g2 -> UnsafeEta -//│ deforest > call f@result @ h1@h1 -> UnsafeEta -//│ deforest > call f@result @ h1@h1 -> UnsafeEta -//│ deforest > call f@result @ h2@h2 -> UnsafeEta -//│ deforest > call f@result @ h2@h2 -> UnsafeEta -//│ deforest > call g1@result @ f@f -> UnsafeEta -//│ deforest > call g1@result @ f@f -> UnsafeEta -//│ deforest > call g1@result @ g1@g1 -> UnsafeEta -//│ deforest > call g1@result @ g2@g2 -> UnsafeEta -//│ deforest > call g1@result @ h1@h1 -> UnsafeEta -//│ deforest > call g1@result @ h2@h2 -> UnsafeEta -//│ deforest > call g2@result @ f@f -> UnsafeEta -//│ deforest > call g2@result @ f@f -> UnsafeEta -//│ deforest > call g2@result @ g1@g1 -> UnsafeEta -//│ deforest > call g2@result @ g2@g2 -> UnsafeEta -//│ deforest > call g2@result @ h1@h1 -> UnsafeEta -//│ deforest > call g2@result @ h2@h2 -> UnsafeEta -//│ deforest > call h1@result @ f@f -> UnsafeEta -//│ deforest > call h1@result @ f@f -> UnsafeEta -//│ deforest > call h1@result @ g1@g1 -> UnsafeEta -//│ deforest > call h1@result @ g2@g2 -> UnsafeEta -//│ deforest > call h1@result @ h1@h1 -> UnsafeEta -//│ deforest > call h1@result @ h2@h2 -> UnsafeEta -//│ deforest > call h2@result @ f@f -> UnsafeEta -//│ deforest > call h2@result @ f@f -> UnsafeEta -//│ deforest > call h2@result @ g1@g1 -> UnsafeEta -//│ deforest > call h2@result @ g2@g2 -> UnsafeEta -//│ deforest > call h2@result @ h1@h1 -> UnsafeEta -//│ deforest > call h2@result @ h2@h2 -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ g1¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ g2⁰ -> UnsafeEta +//│ deforest > function f⁰#0 @ h1¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ h2¹ -> UnsafeEta +//│ deforest > function g1⁰#0 @ f² -> UnsafeEta +//│ deforest > function g1⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function g1⁰#0 @ g1¹ -> UnsafeEta +//│ deforest > function g1⁰#0 @ g2⁰ -> UnsafeEta +//│ deforest > function g1⁰#0 @ h1¹ -> UnsafeEta +//│ deforest > function g1⁰#0 @ h2¹ -> UnsafeEta +//│ deforest > function g2¹#0 @ f² -> UnsafeEta +//│ deforest > function g2¹#0 @ f¹ -> UnsafeEta +//│ deforest > function g2¹#0 @ g1¹ -> UnsafeEta +//│ deforest > function g2¹#0 @ g2⁰ -> UnsafeEta +//│ deforest > function g2¹#0 @ h1¹ -> UnsafeEta +//│ deforest > function g2¹#0 @ h2¹ -> UnsafeEta +//│ deforest > function h1⁰#0 @ f² -> UnsafeEta +//│ deforest > function h1⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function h1⁰#0 @ g1¹ -> UnsafeEta +//│ deforest > function h1⁰#0 @ g2⁰ -> UnsafeEta +//│ deforest > function h1⁰#0 @ h1¹ -> UnsafeEta +//│ deforest > function h1⁰#0 @ h2¹ -> UnsafeEta +//│ deforest > function h2⁰#0 @ f² -> UnsafeEta +//│ deforest > function h2⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function h2⁰#0 @ g1¹ -> UnsafeEta +//│ deforest > function h2⁰#0 @ g2⁰ -> UnsafeEta +//│ deforest > function h2⁰#0 @ h1¹ -> UnsafeEta +//│ deforest > function h2⁰#0 @ h2¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ f² -> Pure +//│ deforest > call +⁰@result² @ f¹ -> Pure +//│ deforest > call +⁰@result² @ g1¹ -> Pure +//│ deforest > call +⁰@result² @ g2⁰ -> Pure +//│ deforest > call +⁰@result² @ h1¹ -> Pure +//│ deforest > call +⁰@result² @ h2¹ -> Pure +//│ deforest > call f⁰@result⁴ @ f² -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ g1¹ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ g2⁰ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ h1¹ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ h2¹ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ f² -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ g1¹ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ g2⁰ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ h1¹ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ h2¹ -> UnsafeEta +//│ deforest > call g1⁰@result⁵ @ f² -> UnsafeEta +//│ deforest > call g1⁰@result⁵ @ f¹ -> UnsafeEta +//│ deforest > call g1⁰@result⁵ @ g1¹ -> UnsafeEta +//│ deforest > call g1⁰@result⁵ @ g2⁰ -> UnsafeEta +//│ deforest > call g1⁰@result⁵ @ h1¹ -> UnsafeEta +//│ deforest > call g1⁰@result⁵ @ h2¹ -> UnsafeEta +//│ deforest > call g2¹@result³ @ f² -> UnsafeEta +//│ deforest > call g2¹@result³ @ f¹ -> UnsafeEta +//│ deforest > call g2¹@result³ @ g1¹ -> UnsafeEta +//│ deforest > call g2¹@result³ @ g2⁰ -> UnsafeEta +//│ deforest > call g2¹@result³ @ h1¹ -> UnsafeEta +//│ deforest > call g2¹@result³ @ h2¹ -> UnsafeEta +//│ deforest > call h1⁰@result⁰ @ f² -> UnsafeEta +//│ deforest > call h1⁰@result⁰ @ f¹ -> UnsafeEta +//│ deforest > call h1⁰@result⁰ @ g1¹ -> UnsafeEta +//│ deforest > call h1⁰@result⁰ @ g2⁰ -> UnsafeEta +//│ deforest > call h1⁰@result⁰ @ h1¹ -> UnsafeEta +//│ deforest > call h1⁰@result⁰ @ h2¹ -> UnsafeEta +//│ deforest > call h2⁰@result¹ @ f² -> UnsafeEta +//│ deforest > call h2⁰@result¹ @ f¹ -> UnsafeEta +//│ deforest > call h2⁰@result¹ @ g1¹ -> UnsafeEta +//│ deforest > call h2⁰@result¹ @ g2⁰ -> UnsafeEta +//│ deforest > call h2⁰@result¹ @ h1¹ -> UnsafeEta +//│ deforest > call h2⁰@result¹ @ h2¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> @@ -1782,102 +1782,102 @@ fun g() = f() fun f() = h1() + h2() [h1, h2, g, f] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ h1@h1 -> Pure -//│ deforest > function f#0 @ h1@h1 -> Pure -//│ deforest > function f#0 @ h2@h2 -> Pure -//│ deforest > function f#0 @ h2@h2 -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ h1@h1 -> Pure -//│ deforest > function g#0 @ h1@h1 -> Pure -//│ deforest > function g#0 @ h2@h2 -> Pure -//│ deforest > function g#0 @ h2@h2 -> Pure -//│ deforest > function h1#0 @ f@f -> Pure -//│ deforest > function h1#0 @ f@f -> Pure -//│ deforest > function h1#0 @ g@g -> Pure -//│ deforest > function h1#0 @ g@g -> Pure -//│ deforest > function h1#0 @ h1@h1 -> Pure -//│ deforest > function h1#0 @ h1@h1 -> Pure -//│ deforest > function h1#0 @ h2@h2 -> Pure -//│ deforest > function h1#0 @ h2@h2 -> Pure -//│ deforest > function h2#0 @ f@f -> Pure -//│ deforest > function h2#0 @ f@f -> Pure -//│ deforest > function h2#0 @ g@g -> Pure -//│ deforest > function h2#0 @ g@g -> Pure -//│ deforest > function h2#0 @ h1@h1 -> Pure -//│ deforest > function h2#0 @ h1@h1 -> Pure -//│ deforest > function h2#0 @ h2@h2 -> Pure -//│ deforest > function h2#0 @ h2@h2 -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h1@h1 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call +@result @ h2@h2 -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ h1@h1 -> Pure -//│ deforest > call f@result @ h1@h1 -> Pure -//│ deforest > call f@result @ h2@h2 -> Pure -//│ deforest > call f@result @ h2@h2 -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h1@h1 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call g@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ f@f -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ g@g -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h1@h1 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h1@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ f@f -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ g@g -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h1@h1 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure -//│ deforest > call h2@result @ h2@h2 -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function f¹#0 @ g² -> Pure +//│ deforest > function f¹#0 @ g¹ -> Pure +//│ deforest > function f¹#0 @ h1² -> Pure +//│ deforest > function f¹#0 @ h1¹ -> Pure +//│ deforest > function f¹#0 @ h2² -> Pure +//│ deforest > function f¹#0 @ h2¹ -> Pure +//│ deforest > function g⁰#0 @ f² -> Pure +//│ deforest > function g⁰#0 @ f⁰ -> Pure +//│ deforest > function g⁰#0 @ g² -> Pure +//│ deforest > function g⁰#0 @ g¹ -> Pure +//│ deforest > function g⁰#0 @ h1² -> Pure +//│ deforest > function g⁰#0 @ h1¹ -> Pure +//│ deforest > function g⁰#0 @ h2² -> Pure +//│ deforest > function g⁰#0 @ h2¹ -> Pure +//│ deforest > function h1⁰#0 @ f² -> Pure +//│ deforest > function h1⁰#0 @ f⁰ -> Pure +//│ deforest > function h1⁰#0 @ g² -> Pure +//│ deforest > function h1⁰#0 @ g¹ -> Pure +//│ deforest > function h1⁰#0 @ h1² -> Pure +//│ deforest > function h1⁰#0 @ h1¹ -> Pure +//│ deforest > function h1⁰#0 @ h2² -> Pure +//│ deforest > function h1⁰#0 @ h2¹ -> Pure +//│ deforest > function h2⁰#0 @ f² -> Pure +//│ deforest > function h2⁰#0 @ f⁰ -> Pure +//│ deforest > function h2⁰#0 @ g² -> Pure +//│ deforest > function h2⁰#0 @ g¹ -> Pure +//│ deforest > function h2⁰#0 @ h1² -> Pure +//│ deforest > function h2⁰#0 @ h1¹ -> Pure +//│ deforest > function h2⁰#0 @ h2² -> Pure +//│ deforest > function h2⁰#0 @ h2¹ -> Pure +//│ deforest > call +⁰@result⁴ @ f² -> Pure +//│ deforest > call +⁰@result⁴ @ f⁰ -> Pure +//│ deforest > call +⁰@result⁴ @ g² -> Pure +//│ deforest > call +⁰@result⁴ @ g¹ -> Pure +//│ deforest > call +⁰@result⁴ @ h1² -> Pure +//│ deforest > call +⁰@result⁴ @ h1¹ -> Pure +//│ deforest > call +⁰@result⁴ @ h2² -> Pure +//│ deforest > call +⁰@result⁴ @ h2¹ -> Pure +//│ deforest > call +⁰@result⁷ @ f² -> Pure +//│ deforest > call +⁰@result⁷ @ f⁰ -> Pure +//│ deforest > call +⁰@result⁷ @ g² -> Pure +//│ deforest > call +⁰@result⁷ @ g¹ -> Pure +//│ deforest > call +⁰@result⁷ @ h1² -> Pure +//│ deforest > call +⁰@result⁷ @ h1¹ -> Pure +//│ deforest > call +⁰@result⁷ @ h2² -> Pure +//│ deforest > call +⁰@result⁷ @ h2¹ -> Pure +//│ deforest > call f¹@result¹ @ f² -> Pure +//│ deforest > call f¹@result¹ @ f⁰ -> Pure +//│ deforest > call f¹@result¹ @ g² -> Pure +//│ deforest > call f¹@result¹ @ g¹ -> Pure +//│ deforest > call f¹@result¹ @ h1² -> Pure +//│ deforest > call f¹@result¹ @ h1¹ -> Pure +//│ deforest > call f¹@result¹ @ h2² -> Pure +//│ deforest > call f¹@result¹ @ h2¹ -> Pure +//│ deforest > call g⁰@result⁰ @ f² -> Pure +//│ deforest > call g⁰@result⁰ @ f⁰ -> Pure +//│ deforest > call g⁰@result⁰ @ g² -> Pure +//│ deforest > call g⁰@result⁰ @ g¹ -> Pure +//│ deforest > call g⁰@result⁰ @ h1² -> Pure +//│ deforest > call g⁰@result⁰ @ h1¹ -> Pure +//│ deforest > call g⁰@result⁰ @ h2² -> Pure +//│ deforest > call g⁰@result⁰ @ h2¹ -> Pure +//│ deforest > call g⁰@result⁵ @ f² -> Pure +//│ deforest > call g⁰@result⁵ @ f⁰ -> Pure +//│ deforest > call g⁰@result⁵ @ g² -> Pure +//│ deforest > call g⁰@result⁵ @ g¹ -> Pure +//│ deforest > call g⁰@result⁵ @ h1² -> Pure +//│ deforest > call g⁰@result⁵ @ h1¹ -> Pure +//│ deforest > call g⁰@result⁵ @ h2² -> Pure +//│ deforest > call g⁰@result⁵ @ h2¹ -> Pure +//│ deforest > call h1⁰@result² @ f² -> Pure +//│ deforest > call h1⁰@result² @ f⁰ -> Pure +//│ deforest > call h1⁰@result² @ g² -> Pure +//│ deforest > call h1⁰@result² @ g¹ -> Pure +//│ deforest > call h1⁰@result² @ h1² -> Pure +//│ deforest > call h1⁰@result² @ h1¹ -> Pure +//│ deforest > call h1⁰@result² @ h2² -> Pure +//│ deforest > call h1⁰@result² @ h2¹ -> Pure +//│ deforest > call h2⁰@result³ @ f² -> Pure +//│ deforest > call h2⁰@result³ @ f⁰ -> Pure +//│ deforest > call h2⁰@result³ @ g² -> Pure +//│ deforest > call h2⁰@result³ @ g¹ -> Pure +//│ deforest > call h2⁰@result³ @ h1² -> Pure +//│ deforest > call h2⁰@result³ @ h1¹ -> Pure +//│ deforest > call h2⁰@result³ @ h2² -> Pure +//│ deforest > call h2⁰@result³ @ h2¹ -> Pure +//│ deforest > call h2⁰@result⁶ @ f² -> Pure +//│ deforest > call h2⁰@result⁶ @ f⁰ -> Pure +//│ deforest > call h2⁰@result⁶ @ g² -> Pure +//│ deforest > call h2⁰@result⁶ @ g¹ -> Pure +//│ deforest > call h2⁰@result⁶ @ h1² -> Pure +//│ deforest > call h2⁰@result⁶ @ h1¹ -> Pure +//│ deforest > call h2⁰@result⁶ @ h2² -> Pure +//│ deforest > call h2⁰@result⁶ @ h2¹ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1888,22 +1888,22 @@ fun g() = f() fun f() = g() [g, f] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function f#0 @ g@g -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ f@f -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call f@result @ g@g -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ g@g -> Pure -//│ deforest > call g@result @ g@g -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function f¹#0 @ g² -> Pure +//│ deforest > function f¹#0 @ g¹ -> Pure +//│ deforest > function g⁰#0 @ f² -> Pure +//│ deforest > function g⁰#0 @ f⁰ -> Pure +//│ deforest > function g⁰#0 @ g² -> Pure +//│ deforest > function g⁰#0 @ g¹ -> Pure +//│ deforest > call f¹@result⁰ @ f² -> Pure +//│ deforest > call f¹@result⁰ @ f⁰ -> Pure +//│ deforest > call f¹@result⁰ @ g² -> Pure +//│ deforest > call f¹@result⁰ @ g¹ -> Pure +//│ deforest > call g⁰@result¹ @ f² -> Pure +//│ deforest > call g⁰@result¹ @ f⁰ -> Pure +//│ deforest > call g⁰@result¹ @ g² -> Pure +//│ deforest > call g⁰@result¹ @ g¹ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1916,18 +1916,18 @@ fun g() = 0 fun f() = f() + g() [f, g] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function g#0 @ f@f.g@g -> Pure -//│ deforest > function g#0 @ f@f.g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function g⁰#0 @ f².g¹ -> Pure +//│ deforest > function g⁰#0 @ f⁰.g¹ -> Pure +//│ deforest > function g⁰#0 @ g² -> Pure +//│ deforest > function g⁰#0 @ g³ -> Pure +//│ deforest > call +⁰@result² @ f² -> Pure +//│ deforest > call +⁰@result² @ f⁰ -> Pure +//│ deforest > call f¹@result⁰ @ f² -> Pure +//│ deforest > call f¹@result⁰ @ f⁰ -> Pure +//│ deforest > call g⁰@result¹ @ f² -> Pure +//│ deforest > call g⁰@result¹ @ f⁰ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1946,118 +1946,118 @@ fun f() = [g1(), g2(), g3(), g4(), h(B)] f //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g1@g1 -> Pure -//│ deforest > function f#0 @ g2@g2 -> Pure -//│ deforest > function f#0 @ g3@g3 -> Pure -//│ deforest > function f#0 @ g4@g4 -> Pure -//│ deforest > function f#0 @ h@h -> Pure -//│ deforest > function g1#0 @ f@f -> Pure -//│ deforest > function g1#0 @ f@f -> Pure -//│ deforest > function g1#0 @ g1@g1 -> Pure -//│ deforest > function g1#0 @ g2@g2 -> Pure -//│ deforest > function g1#0 @ g3@g3 -> Pure -//│ deforest > function g1#0 @ g4@g4 -> Pure -//│ deforest > function g1#0 @ h@h -> Pure -//│ deforest > function g2#0 @ f@f -> Pure -//│ deforest > function g2#0 @ f@f -> Pure -//│ deforest > function g2#0 @ g1@g1 -> Pure -//│ deforest > function g2#0 @ g2@g2 -> Pure -//│ deforest > function g2#0 @ g3@g3 -> Pure -//│ deforest > function g2#0 @ g4@g4 -> Pure -//│ deforest > function g2#0 @ h@h -> Pure -//│ deforest > function g3#0 @ f@f -> Pure -//│ deforest > function g3#0 @ f@f -> Pure -//│ deforest > function g3#0 @ g1@g1 -> Pure -//│ deforest > function g3#0 @ g2@g2 -> Pure -//│ deforest > function g3#0 @ g3@g3 -> Pure -//│ deforest > function g3#0 @ g4@g4 -> Pure -//│ deforest > function g3#0 @ h@h -> Pure -//│ deforest > function g4#0 @ f@f -> Pure -//│ deforest > function g4#0 @ f@f -> Pure -//│ deforest > function g4#0 @ g1@g1 -> Pure -//│ deforest > function g4#0 @ g2@g2 -> Pure -//│ deforest > function g4#0 @ g3@g3 -> Pure -//│ deforest > function g4#0 @ g4@g4 -> Pure -//│ deforest > function g4#0 @ h@h -> Pure -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function h#0 @ g1@g1 -> Pure -//│ deforest > function h#0 @ g2@g2 -> Pure -//│ deforest > function h#0 @ g3@g3 -> Pure -//│ deforest > function h#0 @ g4@g4 -> Pure -//│ deforest > function h#0 @ h@h -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g1@g1 -> Pure -//│ deforest > call f@result @ g2@g2 -> Pure -//│ deforest > call f@result @ g3@g3 -> Pure -//│ deforest > call f@result @ g4@g4 -> Pure -//│ deforest > call f@result @ h@h -> Pure -//│ deforest > call g1@result @ f@f -> Pure -//│ deforest > call g1@result @ f@f -> Pure -//│ deforest > call g1@result @ g1@g1 -> Pure -//│ deforest > call g1@result @ g2@g2 -> Pure -//│ deforest > call g1@result @ g3@g3 -> Pure -//│ deforest > call g1@result @ g4@g4 -> Pure -//│ deforest > call g1@result @ h@h -> Pure -//│ deforest > call g2@result @ f@f -> Pure -//│ deforest > call g2@result @ f@f -> Pure -//│ deforest > call g2@result @ g1@g1 -> Pure -//│ deforest > call g2@result @ g2@g2 -> Pure -//│ deforest > call g2@result @ g3@g3 -> Pure -//│ deforest > call g2@result @ g4@g4 -> Pure -//│ deforest > call g2@result @ h@h -> Pure -//│ deforest > call g3@result @ f@f -> Pure -//│ deforest > call g3@result @ f@f -> Pure -//│ deforest > call g3@result @ g1@g1 -> Pure -//│ deforest > call g3@result @ g2@g2 -> Pure -//│ deforest > call g3@result @ g3@g3 -> Pure -//│ deforest > call g3@result @ g4@g4 -> Pure -//│ deforest > call g3@result @ h@h -> Pure -//│ deforest > call g4@result @ f@f -> Pure -//│ deforest > call g4@result @ f@f -> Pure -//│ deforest > call g4@result @ g1@g1 -> Pure -//│ deforest > call g4@result @ g2@g2 -> Pure -//│ deforest > call g4@result @ g3@g3 -> Pure -//│ deforest > call g4@result @ g4@g4 -> Pure -//│ deforest > call g4@result @ h@h -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ g1@g1 -> Pure -//│ deforest > call h@result @ g1@g1 -> Pure -//│ deforest > call h@result @ g1@g1 -> Pure -//│ deforest > call h@result @ g1@g1 -> Pure -//│ deforest > call h@result @ g1@g1 -> Pure -//│ deforest > call h@result @ g2@g2 -> Pure -//│ deforest > call h@result @ g2@g2 -> Pure -//│ deforest > call h@result @ g2@g2 -> Pure -//│ deforest > call h@result @ g2@g2 -> Pure -//│ deforest > call h@result @ g2@g2 -> Pure -//│ deforest > call h@result @ g3@g3 -> Pure -//│ deforest > call h@result @ g3@g3 -> Pure -//│ deforest > call h@result @ g3@g3 -> Pure -//│ deforest > call h@result @ g3@g3 -> Pure -//│ deforest > call h@result @ g3@g3 -> Pure -//│ deforest > call h@result @ g4@g4 -> Pure -//│ deforest > call h@result @ g4@g4 -> Pure -//│ deforest > call h@result @ g4@g4 -> Pure -//│ deforest > call h@result @ g4@g4 -> Pure -//│ deforest > call h@result @ g4@g4 -> Pure -//│ deforest > call h@result @ h@h -> Pure -//│ deforest > call h@result @ h@h -> Pure -//│ deforest > call h@result @ h@h -> Pure -//│ deforest > call h@result @ h@h -> Pure -//│ deforest > call h@result @ h@h -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function f¹#0 @ g1¹ -> Pure +//│ deforest > function f¹#0 @ g2¹ -> Pure +//│ deforest > function f¹#0 @ g3¹ -> Pure +//│ deforest > function f¹#0 @ g4¹ -> Pure +//│ deforest > function f¹#0 @ h³ -> Pure +//│ deforest > function g1⁰#0 @ f² -> Pure +//│ deforest > function g1⁰#0 @ f⁰ -> Pure +//│ deforest > function g1⁰#0 @ g1¹ -> Pure +//│ deforest > function g1⁰#0 @ g2¹ -> Pure +//│ deforest > function g1⁰#0 @ g3¹ -> Pure +//│ deforest > function g1⁰#0 @ g4¹ -> Pure +//│ deforest > function g1⁰#0 @ h³ -> Pure +//│ deforest > function g2⁰#0 @ f² -> Pure +//│ deforest > function g2⁰#0 @ f⁰ -> Pure +//│ deforest > function g2⁰#0 @ g1¹ -> Pure +//│ deforest > function g2⁰#0 @ g2¹ -> Pure +//│ deforest > function g2⁰#0 @ g3¹ -> Pure +//│ deforest > function g2⁰#0 @ g4¹ -> Pure +//│ deforest > function g2⁰#0 @ h³ -> Pure +//│ deforest > function g3⁰#0 @ f² -> Pure +//│ deforest > function g3⁰#0 @ f⁰ -> Pure +//│ deforest > function g3⁰#0 @ g1¹ -> Pure +//│ deforest > function g3⁰#0 @ g2¹ -> Pure +//│ deforest > function g3⁰#0 @ g3¹ -> Pure +//│ deforest > function g3⁰#0 @ g4¹ -> Pure +//│ deforest > function g3⁰#0 @ h³ -> Pure +//│ deforest > function g4⁰#0 @ f² -> Pure +//│ deforest > function g4⁰#0 @ f⁰ -> Pure +//│ deforest > function g4⁰#0 @ g1¹ -> Pure +//│ deforest > function g4⁰#0 @ g2¹ -> Pure +//│ deforest > function g4⁰#0 @ g3¹ -> Pure +//│ deforest > function g4⁰#0 @ g4¹ -> Pure +//│ deforest > function g4⁰#0 @ h³ -> Pure +//│ deforest > function h²#0 @ f² -> Pure +//│ deforest > function h²#0 @ f⁰ -> Pure +//│ deforest > function h²#0 @ g1¹ -> Pure +//│ deforest > function h²#0 @ g2¹ -> Pure +//│ deforest > function h²#0 @ g3¹ -> Pure +//│ deforest > function h²#0 @ g4¹ -> Pure +//│ deforest > function h²#0 @ h³ -> Pure +//│ deforest > call f¹@result⁰ @ f² -> Pure +//│ deforest > call f¹@result⁰ @ f⁰ -> Pure +//│ deforest > call f¹@result⁰ @ g1¹ -> Pure +//│ deforest > call f¹@result⁰ @ g2¹ -> Pure +//│ deforest > call f¹@result⁰ @ g3¹ -> Pure +//│ deforest > call f¹@result⁰ @ g4¹ -> Pure +//│ deforest > call f¹@result⁰ @ h³ -> Pure +//│ deforest > call g1⁰@result¹ @ f² -> Pure +//│ deforest > call g1⁰@result¹ @ f⁰ -> Pure +//│ deforest > call g1⁰@result¹ @ g1¹ -> Pure +//│ deforest > call g1⁰@result¹ @ g2¹ -> Pure +//│ deforest > call g1⁰@result¹ @ g3¹ -> Pure +//│ deforest > call g1⁰@result¹ @ g4¹ -> Pure +//│ deforest > call g1⁰@result¹ @ h³ -> Pure +//│ deforest > call g2⁰@result² @ f² -> Pure +//│ deforest > call g2⁰@result² @ f⁰ -> Pure +//│ deforest > call g2⁰@result² @ g1¹ -> Pure +//│ deforest > call g2⁰@result² @ g2¹ -> Pure +//│ deforest > call g2⁰@result² @ g3¹ -> Pure +//│ deforest > call g2⁰@result² @ g4¹ -> Pure +//│ deforest > call g2⁰@result² @ h³ -> Pure +//│ deforest > call g3⁰@result³ @ f² -> Pure +//│ deforest > call g3⁰@result³ @ f⁰ -> Pure +//│ deforest > call g3⁰@result³ @ g1¹ -> Pure +//│ deforest > call g3⁰@result³ @ g2¹ -> Pure +//│ deforest > call g3⁰@result³ @ g3¹ -> Pure +//│ deforest > call g3⁰@result³ @ g4¹ -> Pure +//│ deforest > call g3⁰@result³ @ h³ -> Pure +//│ deforest > call g4⁰@result⁴ @ f² -> Pure +//│ deforest > call g4⁰@result⁴ @ f⁰ -> Pure +//│ deforest > call g4⁰@result⁴ @ g1¹ -> Pure +//│ deforest > call g4⁰@result⁴ @ g2¹ -> Pure +//│ deforest > call g4⁰@result⁴ @ g3¹ -> Pure +//│ deforest > call g4⁰@result⁴ @ g4¹ -> Pure +//│ deforest > call g4⁰@result⁴ @ h³ -> Pure +//│ deforest > call h²@result⁵ @ f² -> Pure +//│ deforest > call h²@result⁵ @ f⁰ -> Pure +//│ deforest > call h²@result⁵ @ g1¹ -> Pure +//│ deforest > call h²@result⁵ @ g2¹ -> Pure +//│ deforest > call h²@result⁵ @ g3¹ -> Pure +//│ deforest > call h²@result⁵ @ g4¹ -> Pure +//│ deforest > call h²@result⁵ @ h³ -> Pure +//│ deforest > call h²@result⁶ @ f² -> Pure +//│ deforest > call h²@result⁶ @ f⁰ -> Pure +//│ deforest > call h²@result⁶ @ g1¹ -> Pure +//│ deforest > call h²@result⁶ @ g2¹ -> Pure +//│ deforest > call h²@result⁶ @ g3¹ -> Pure +//│ deforest > call h²@result⁶ @ g4¹ -> Pure +//│ deforest > call h²@result⁶ @ h³ -> Pure +//│ deforest > call h²@result⁷ @ f² -> Pure +//│ deforest > call h²@result⁷ @ f⁰ -> Pure +//│ deforest > call h²@result⁷ @ g1¹ -> Pure +//│ deforest > call h²@result⁷ @ g2¹ -> Pure +//│ deforest > call h²@result⁷ @ g3¹ -> Pure +//│ deforest > call h²@result⁷ @ g4¹ -> Pure +//│ deforest > call h²@result⁷ @ h³ -> Pure +//│ deforest > call h²@result⁸ @ f² -> Pure +//│ deforest > call h²@result⁸ @ f⁰ -> Pure +//│ deforest > call h²@result⁸ @ g1¹ -> Pure +//│ deforest > call h²@result⁸ @ g2¹ -> Pure +//│ deforest > call h²@result⁸ @ g3¹ -> Pure +//│ deforest > call h²@result⁸ @ g4¹ -> Pure +//│ deforest > call h²@result⁸ @ h³ -> Pure +//│ deforest > call h²@result⁹ @ f² -> Pure +//│ deforest > call h²@result⁹ @ f⁰ -> Pure +//│ deforest > call h²@result⁹ @ g1¹ -> Pure +//│ deforest > call h²@result⁹ @ g2¹ -> Pure +//│ deforest > call h²@result⁹ @ g3¹ -> Pure +//│ deforest > call h²@result⁹ @ g4¹ -> Pure +//│ deforest > call h²@result⁹ @ h³ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> @@ -2134,51 +2134,51 @@ fun f() = [g1(), g2()] f //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ g1@g1 -> Pure -//│ deforest > function f#0 @ g2@g2 -> Pure -//│ deforest > function f#0 @ h@h -> Pure -//│ deforest > function g1#0 @ f@f -> Pure -//│ deforest > function g1#0 @ f@f -> Pure -//│ deforest > function g1#0 @ g1@g1 -> Pure -//│ deforest > function g1#0 @ g2@g2 -> Pure -//│ deforest > function g1#0 @ h@h -> Pure -//│ deforest > function g2#0 @ f@f -> Pure -//│ deforest > function g2#0 @ f@f -> Pure -//│ deforest > function g2#0 @ g1@g1 -> Pure -//│ deforest > function g2#0 @ g2@g2 -> Pure -//│ deforest > function g2#0 @ h@h -> Pure -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function h#0 @ f@f -> Pure -//│ deforest > function h#0 @ g1@g1 -> Pure -//│ deforest > function h#0 @ g2@g2 -> Pure -//│ deforest > function h#0 @ h@h -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ f@f -> Pure -//│ deforest > call f@result @ g1@g1 -> Pure -//│ deforest > call f@result @ g2@g2 -> Pure -//│ deforest > call f@result @ h@h -> Pure -//│ deforest > call g1@result @ f@f -> Pure -//│ deforest > call g1@result @ f@f -> Pure -//│ deforest > call g1@result @ g1@g1 -> Pure -//│ deforest > call g1@result @ g2@g2 -> Pure -//│ deforest > call g1@result @ h@h -> Pure -//│ deforest > call g2@result @ f@f -> Pure -//│ deforest > call g2@result @ f@f -> Pure -//│ deforest > call g2@result @ g1@g1 -> Pure -//│ deforest > call g2@result @ g2@g2 -> Pure -//│ deforest > call g2@result @ h@h -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ f@f -> Pure -//│ deforest > call h@result @ g1@g1 -> Pure -//│ deforest > call h@result @ g1@g1 -> Pure -//│ deforest > call h@result @ g2@g2 -> Pure -//│ deforest > call h@result @ g2@g2 -> Pure -//│ deforest > call h@result @ h@h -> Pure -//│ deforest > call h@result @ h@h -> Pure +//│ deforest > function f¹#0 @ f² -> Pure +//│ deforest > function f¹#0 @ f⁰ -> Pure +//│ deforest > function f¹#0 @ g1¹ -> Pure +//│ deforest > function f¹#0 @ g2¹ -> Pure +//│ deforest > function f¹#0 @ h³ -> Pure +//│ deforest > function g1⁰#0 @ f² -> Pure +//│ deforest > function g1⁰#0 @ f⁰ -> Pure +//│ deforest > function g1⁰#0 @ g1¹ -> Pure +//│ deforest > function g1⁰#0 @ g2¹ -> Pure +//│ deforest > function g1⁰#0 @ h³ -> Pure +//│ deforest > function g2⁰#0 @ f² -> Pure +//│ deforest > function g2⁰#0 @ f⁰ -> Pure +//│ deforest > function g2⁰#0 @ g1¹ -> Pure +//│ deforest > function g2⁰#0 @ g2¹ -> Pure +//│ deforest > function g2⁰#0 @ h³ -> Pure +//│ deforest > function h²#0 @ f² -> Pure +//│ deforest > function h²#0 @ f⁰ -> Pure +//│ deforest > function h²#0 @ g1¹ -> Pure +//│ deforest > function h²#0 @ g2¹ -> Pure +//│ deforest > function h²#0 @ h³ -> Pure +//│ deforest > call f¹@result⁰ @ f² -> Pure +//│ deforest > call f¹@result⁰ @ f⁰ -> Pure +//│ deforest > call f¹@result⁰ @ g1¹ -> Pure +//│ deforest > call f¹@result⁰ @ g2¹ -> Pure +//│ deforest > call f¹@result⁰ @ h³ -> Pure +//│ deforest > call g1⁰@result¹ @ f² -> Pure +//│ deforest > call g1⁰@result¹ @ f⁰ -> Pure +//│ deforest > call g1⁰@result¹ @ g1¹ -> Pure +//│ deforest > call g1⁰@result¹ @ g2¹ -> Pure +//│ deforest > call g1⁰@result¹ @ h³ -> Pure +//│ deforest > call g2⁰@result² @ f² -> Pure +//│ deforest > call g2⁰@result² @ f⁰ -> Pure +//│ deforest > call g2⁰@result² @ g1¹ -> Pure +//│ deforest > call g2⁰@result² @ g2¹ -> Pure +//│ deforest > call g2⁰@result² @ h³ -> Pure +//│ deforest > call h²@result³ @ f² -> Pure +//│ deforest > call h²@result³ @ f⁰ -> Pure +//│ deforest > call h²@result³ @ g1¹ -> Pure +//│ deforest > call h²@result³ @ g2¹ -> Pure +//│ deforest > call h²@result³ @ h³ -> Pure +//│ deforest > call h²@result⁴ @ f² -> Pure +//│ deforest > call h²@result⁴ @ f⁰ -> Pure +//│ deforest > call h²@result⁴ @ g1¹ -> Pure +//│ deforest > call h²@result⁴ @ g2¹ -> Pure +//│ deforest > call h²@result⁴ @ h³ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> @@ -2212,30 +2212,30 @@ fun f() = [() => h(B), () => h(B), () => h(B), () => h(B), h(B)] f //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function h#0 @ f@f -> UnsafeEta -//│ deforest > function h#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > function lambda#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > function f¹#0 @ f² -> UnsafeEta +//│ deforest > function f¹#0 @ f⁰ -> UnsafeEta +//│ deforest > function h²#0 @ f² -> UnsafeEta +//│ deforest > function h²#0 @ f⁰ -> UnsafeEta +//│ deforest > function lambda²#0 @ f² -> UnsafeEta +//│ deforest > function lambda²#0 @ f⁰ -> UnsafeEta +//│ deforest > function lambda³#0 @ f² -> UnsafeEta +//│ deforest > function lambda³#0 @ f⁰ -> UnsafeEta +//│ deforest > function lambda¹#0 @ f² -> UnsafeEta +//│ deforest > function lambda¹#0 @ f⁰ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ f² -> UnsafeEta +//│ deforest > function lambda⁰#0 @ f⁰ -> UnsafeEta +//│ deforest > call f¹@result⁰ @ f² -> UnsafeEta +//│ deforest > call f¹@result⁰ @ f⁰ -> UnsafeEta +//│ deforest > call h²@result² @ f² -> UnsafeEta +//│ deforest > call h²@result² @ f⁰ -> UnsafeEta +//│ deforest > call h²@result³ @ f² -> UnsafeEta +//│ deforest > call h²@result³ @ f⁰ -> UnsafeEta +//│ deforest > call h²@result¹ @ f² -> UnsafeEta +//│ deforest > call h²@result¹ @ f⁰ -> UnsafeEta +//│ deforest > call h²@result⁴ @ f² -> UnsafeEta +//│ deforest > call h²@result⁴ @ f⁰ -> UnsafeEta +//│ deforest > call h²@result⁵ @ f² -> UnsafeEta +//│ deforest > call h²@result⁵ @ f⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls b/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls index 47f2cf51e0..84cc8fabbe 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/relaxedPrograms.mls @@ -15,9 +15,9 @@ class Store(n) with val store = Store(1) store.foo(AA(4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call foo@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(Store⁰.this.n⁰) -> @@ -44,9 +44,9 @@ class Store(n) with val store = Store(1) store.foo(AA(4)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call foo@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(Store¹.this.n¹) -> @@ -73,13 +73,13 @@ fun classMethodSibling() = AA(x) then x + store.get() classMethodSibling() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function classMethodSibling#0 @ classMethodSibling@classMethodSibling -> UnsafeEta -//│ deforest > function classMethodSibling#0 @ classMethodSibling@classMethodSibling -> UnsafeEta -//│ deforest > call +@result @ classMethodSibling@classMethodSibling -> Pure -//│ deforest > call +@result @ classMethodSibling@classMethodSibling -> Pure -//│ deforest > call classMethodSibling@result @ -> UnsafeEta -//│ deforest > call get@result @ classMethodSibling@classMethodSibling -> UnsafeEta -//│ deforest > call get@result @ classMethodSibling@classMethodSibling -> UnsafeEta +//│ deforest > function classMethodSibling⁰#0 @ classMethodSibling² -> UnsafeEta +//│ deforest > function classMethodSibling⁰#0 @ classMethodSibling¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ classMethodSibling² -> Pure +//│ deforest > call +⁰@result¹ @ classMethodSibling¹ -> Pure +//│ deforest > call classMethodSibling⁰@result² @ -> UnsafeEta +//│ deforest > call get@result⁰ @ classMethodSibling² -> UnsafeEta +//│ deforest > call get@result⁰ @ classMethodSibling¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> @@ -101,7 +101,7 @@ if AA(1) is AA(x) then x + r!a //│ deforest > >>> effect-analysis results >>> -//│ deforest > call +@result @ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> @@ -119,7 +119,7 @@ if AA(1) is let xs = [0, 1] x + xs!1 //│ deforest > >>> effect-analysis results >>> -//│ deforest > call +@result @ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> @@ -139,11 +139,11 @@ fun nestedClass() = AA(x) then x nestedClass() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function nestedClass#0 @ nestedClass@nestedClass -> UnsafeEta -//│ deforest > function nestedClass#0 @ nestedClass@nestedClass -> UnsafeEta -//│ deforest > call get@result @ nestedClass@nestedClass -> UnsafeEta -//│ deforest > call get@result @ nestedClass@nestedClass -> UnsafeEta -//│ deforest > call nestedClass@result @ -> UnsafeEta +//│ deforest > function nestedClass⁰#0 @ nestedClass² -> UnsafeEta +//│ deforest > function nestedClass⁰#0 @ nestedClass¹ -> UnsafeEta +//│ deforest > call get@result⁰ @ nestedClass² -> UnsafeEta +//│ deforest > call get@result⁰ @ nestedClass¹ -> UnsafeEta +//│ deforest > call nestedClass⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> @@ -165,8 +165,8 @@ fun loopSibling() = if AA(1) is AA(x) then print(x) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function loopSibling#0 @ loopSibling@loopSibling -> UnsafeEta -//│ deforest > call print@result @ loopSibling@loopSibling -> UnsafeEta +//│ deforest > function loopSibling⁰#0 @ loopSibling¹ -> UnsafeEta +//│ deforest > call print@result⁰ @ loopSibling¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> @@ -189,11 +189,11 @@ class C(n) with let c = C(1) c.get() + c.get() //│ deforest > >>> effect-analysis results >>> -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call get@result @ -> UnsafeEta -//│ deforest > call get@result @ -> UnsafeEta +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call get@result² @ -> UnsafeEta +//│ deforest > call get@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> @@ -213,11 +213,11 @@ module M with AA(a) then a + _private M.f() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call f@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> @@ -242,16 +242,16 @@ module M with AA(a) then a + g() M.MM.f() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f.g@g -> Pure -//│ deforest > function g#0 @ f@f.g@g -> Pure -//│ deforest > function g#0 @ g@g -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ f@f -> Pure -//│ deforest > call g@result @ f@f -> Pure +//│ deforest > function f¹#0 @ f² -> UnsafeEta +//│ deforest > function f¹#0 @ f⁰ -> UnsafeEta +//│ deforest > function g⁰#0 @ f².g¹ -> Pure +//│ deforest > function g⁰#0 @ f⁰.g¹ -> Pure +//│ deforest > function g⁰#0 @ g² -> Pure +//│ deforest > call +⁰@result¹ @ f² -> Pure +//│ deforest > call +⁰@result¹ @ f⁰ -> Pure +//│ deforest > call f@result² @ -> UnsafeEta +//│ deforest > call g@result⁰ @ f² -> Pure +//│ deforest > call g@result⁰ @ f⁰ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA¹(1) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls b/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls index 503e818e34..c5dfacd6e5 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/selectionsInNestedMatch.mls @@ -35,9 +35,9 @@ fun c(x) = if x is A then x.AA#x c(AA(2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -58,9 +58,9 @@ fun c(x, y) = if x is A then x.AA#x c(AA(2), A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -81,12 +81,12 @@ fun c(x, y) = if x is fun p() = AA(2) c(p(), A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -109,14 +109,14 @@ fun c(x, y) = if x is fun p() = AA(2) c(p(), A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c¹ -> Pure +//│ deforest > call c⁰@result¹ @ -> UnsafeEta +//│ deforest > call p⁰@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -138,19 +138,19 @@ fun g(x) = if x is A then 42 f(AA(AA(AA(AA(AA(A)))))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ g⁰ -> UnsafeEta +//│ deforest > function g¹#0 @ f² -> UnsafeEta +//│ deforest > function g¹#0 @ f¹ -> UnsafeEta +//│ deforest > function g¹#0 @ g⁰ -> UnsafeEta +//│ deforest > call f⁰@result² @ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ f² -> UnsafeEta +//│ deforest > call f⁰@result¹ @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ g⁰ -> UnsafeEta +//│ deforest > call g¹@result⁰ @ f² -> UnsafeEta +//│ deforest > call g¹@result⁰ @ f¹ -> UnsafeEta +//│ deforest > call g¹@result⁰ @ g⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> @@ -178,9 +178,9 @@ fun f(x) = if x is AA(AA(a)) then a f(AA(AA(A))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁴) -> @@ -198,12 +198,12 @@ fun f(x) = if x is fun p() = AA(AA(A)) f(p()) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ -> UnsafeEta +//│ deforest > call p⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁵) -> @@ -226,11 +226,11 @@ fun c(x, y) = t + y c(AA(2), 10) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c¹ -> Pure +//│ deforest > call c⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/simple.mls b/hkmc2/shared/src/test/mlscript/deforest/simple.mls index 432be98008..5bf86d2b89 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/simple.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/simple.mls @@ -33,17 +33,17 @@ fun test(x) = y + 1 + 2 + 3 + 4 test(AA(AA(10))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ test² -> Pure +//│ deforest > call +⁰@result² @ test¹ -> Pure +//│ deforest > call +⁰@result³ @ test² -> Pure +//│ deforest > call +⁰@result³ @ test¹ -> Pure +//│ deforest > call +⁰@result¹ @ test² -> Pure +//│ deforest > call +⁰@result¹ @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call test⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁰) -> @@ -99,11 +99,11 @@ if x is AA(x) then f(x) BB(x) then f(x) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(B⁰) -> @@ -135,12 +135,12 @@ if x is AA then f1(x.AA#aa) BB then f2(x.BB#bb) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > call f1⁰@result¹ @ -> UnsafeEta +//│ deforest > call f2⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(B⁰) -> @@ -164,12 +164,12 @@ fun c(x) = if x is BB(x) then x c(g(true)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta +//│ deforest > call g⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(11) -> @@ -228,15 +228,15 @@ fun c(a) = x c(A) + c(B) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call print@result @ c@c -> UnsafeEta -//│ deforest > call print@result @ c@c -> UnsafeEta -//│ deforest > call print@result @ c@c -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c³ -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call c⁰@result² @ -> UnsafeEta +//│ deforest > call c⁰@result³ @ -> UnsafeEta +//│ deforest > call print@result⁰ @ c² -> UnsafeEta +//│ deforest > call print@result⁰ @ c³ -> UnsafeEta +//│ deforest > call print@result⁰ @ c¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> @@ -259,11 +259,11 @@ fun c(x) = n + t c(AA(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c¹ -> Pure +//│ deforest > call c⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -277,9 +277,9 @@ fun f(a, b) = if a is B then 3 f(A, B) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -295,15 +295,15 @@ fun f(x) = if x is Some then if x.Some#value > 1 then f(Some(x.Some#value - 1)) else 0 f(Some(2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call >@result @ f@f -> Pure -//│ deforest > call >@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call -⁰@result¹ @ f² -> Pure +//│ deforest > call -⁰@result¹ @ f¹ -> Pure +//│ deforest > call >⁰@result⁰ @ f² -> Pure +//│ deforest > call >⁰@result⁰ @ f¹ -> Pure +//│ deforest > call f⁰@result² @ f² -> UnsafeEta +//│ deforest > call f⁰@result² @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Some⁰(tmp¹) -> @@ -346,43 +346,43 @@ fun f(x, y) = a + 3 f(AAA(1, 3), 1) + f(BBB(2, 3), 2) + f(AAA(3, 2), 4) + f(BBB(4, 6), 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ f⁴ -> UnsafeEta +//│ deforest > function f⁰#0 @ f⁵ -> UnsafeEta +//│ deforest > call +⁰@result² @ f² -> Pure +//│ deforest > call +⁰@result² @ f³ -> Pure +//│ deforest > call +⁰@result² @ f¹ -> Pure +//│ deforest > call +⁰@result² @ f⁴ -> Pure +//│ deforest > call +⁰@result² @ f⁵ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁵ -> Pure +//│ deforest > call +⁰@result⁴ @ f² -> Pure +//│ deforest > call +⁰@result⁴ @ f³ -> Pure +//│ deforest > call +⁰@result⁴ @ f¹ -> Pure +//│ deforest > call +⁰@result⁴ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁴ @ f⁵ -> Pure +//│ deforest > call +⁰@result⁵ @ -> Pure +//│ deforest > call +⁰@result⁷ @ -> Pure +//│ deforest > call +⁰@result⁹ @ -> Pure +//│ deforest > call -⁰@result³ @ f² -> Pure +//│ deforest > call -⁰@result³ @ f³ -> Pure +//│ deforest > call -⁰@result³ @ f¹ -> Pure +//│ deforest > call -⁰@result³ @ f⁴ -> Pure +//│ deforest > call -⁰@result³ @ f⁵ -> Pure +//│ deforest > call -⁰@result¹ @ f² -> Pure +//│ deforest > call -⁰@result¹ @ f³ -> Pure +//│ deforest > call -⁰@result¹ @ f¹ -> Pure +//│ deforest > call -⁰@result¹ @ f⁴ -> Pure +//│ deforest > call -⁰@result¹ @ f⁵ -> Pure +//│ deforest > call f⁰@result¹¹ @ -> UnsafeEta +//│ deforest > call f⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ -> UnsafeEta +//│ deforest > call f⁰@result⁸ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BBB⁰(4, 6) -> @@ -415,21 +415,21 @@ fun c2(x) = if x is fun p(a) = c1(a) + c2(a) p(AA(1)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ p@p.c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ p@p.c1@c1 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ p@p.c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ p@p.c2@c2 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ p@p -> Pure -//│ deforest > call +@result @ p@p -> Pure -//│ deforest > call c1@result @ p@p -> UnsafeEta -//│ deforest > call c1@result @ p@p -> UnsafeEta -//│ deforest > call c2@result @ p@p -> UnsafeEta -//│ deforest > call c2@result @ p@p -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1² -> UnsafeEta +//│ deforest > function c1⁰#0 @ p².c1¹ -> UnsafeEta +//│ deforest > function c1⁰#0 @ p⁰.c1¹ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ p².c2¹ -> UnsafeEta +//│ deforest > function c2⁰#0 @ p⁰.c2¹ -> UnsafeEta +//│ deforest > function p¹#0 @ p² -> UnsafeEta +//│ deforest > function p¹#0 @ p⁰ -> UnsafeEta +//│ deforest > call +⁰@result² @ p² -> Pure +//│ deforest > call +⁰@result² @ p⁰ -> Pure +//│ deforest > call c1⁰@result⁰ @ p² -> UnsafeEta +//│ deforest > call c1⁰@result⁰ @ p⁰ -> UnsafeEta +//│ deforest > call c2⁰@result¹ @ p² -> UnsafeEta +//│ deforest > call c2⁰@result¹ @ p⁰ -> UnsafeEta +//│ deforest > call p¹@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -450,9 +450,9 @@ fun c(x, y) = if x is A then a c(AA(2), A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c⁰#0 @ c² -> UnsafeEta +//│ deforest > function c⁰#0 @ c¹ -> UnsafeEta +//│ deforest > call c⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -472,38 +472,38 @@ fun f(x, y) = a + 3 f(AAA(1, 3), 1) + f(CCC(2), 2) + f(AAA(3, 2), 4) + f(CCC(4), 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ f⁴ -> UnsafeEta +//│ deforest > function f⁰#0 @ f⁵ -> UnsafeEta +//│ deforest > call +⁰@result² @ f² -> Pure +//│ deforest > call +⁰@result² @ f³ -> Pure +//│ deforest > call +⁰@result² @ f¹ -> Pure +//│ deforest > call +⁰@result² @ f⁴ -> Pure +//│ deforest > call +⁰@result² @ f⁵ -> Pure +//│ deforest > call +⁰@result³ @ f² -> Pure +//│ deforest > call +⁰@result³ @ f³ -> Pure +//│ deforest > call +⁰@result³ @ f¹ -> Pure +//│ deforest > call +⁰@result³ @ f⁴ -> Pure +//│ deforest > call +⁰@result³ @ f⁵ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁵ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call +⁰@result⁶ @ -> Pure +//│ deforest > call +⁰@result⁸ @ -> Pure +//│ deforest > call -⁰@result¹ @ f² -> Pure +//│ deforest > call -⁰@result¹ @ f³ -> Pure +//│ deforest > call -⁰@result¹ @ f¹ -> Pure +//│ deforest > call -⁰@result¹ @ f⁴ -> Pure +//│ deforest > call -⁰@result¹ @ f⁵ -> Pure +//│ deforest > call f⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call f⁰@result⁵ @ -> UnsafeEta +//│ deforest > call f⁰@result⁷ @ -> UnsafeEta +//│ deforest > call f⁰@result⁹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > CCC⁰(4) -> @@ -534,27 +534,27 @@ fun f(x, y) = a + 3 f(AAA(1, 3), 1) + f(CCC(2), 2) + f(AAA(3, 2), 4) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ f⁴ -> UnsafeEta +//│ deforest > call +⁰@result² @ f² -> Pure +//│ deforest > call +⁰@result² @ f³ -> Pure +//│ deforest > call +⁰@result² @ f¹ -> Pure +//│ deforest > call +⁰@result² @ f⁴ -> Pure +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result¹ @ f² -> Pure +//│ deforest > call +⁰@result¹ @ f³ -> Pure +//│ deforest > call +⁰@result¹ @ f¹ -> Pure +//│ deforest > call +⁰@result¹ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁰ @ f² -> Pure +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call +⁰@result⁵ @ -> Pure +//│ deforest > call f⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f⁰@result⁶ @ -> UnsafeEta +//│ deforest > call f⁰@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AAA⁰(3, 2) -> @@ -576,11 +576,11 @@ fun c(x, m) = if x is else m c(BB(3), 0) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call +@result @ c@c -> Pure -//│ deforest > call c@result @ -> UnsafeEta +//│ deforest > function c¹#0 @ c² -> UnsafeEta +//│ deforest > function c¹#0 @ c³ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ c² -> Pure +//│ deforest > call +⁰@result⁰ @ c³ -> Pure +//│ deforest > call c¹@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(3) -> @@ -598,17 +598,17 @@ fun g(b) = if b is AA(a) then a + 1 f(AA(AA(0))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f.g@g -> UnsafeEta -//│ deforest > function g#0 @ f@f.g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call +@result @ f@f.g@g -> Pure -//│ deforest > call +@result @ f@f.g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta +//│ deforest > function f¹#0 @ f² -> UnsafeEta +//│ deforest > function f¹#0 @ f⁰ -> UnsafeEta +//│ deforest > function g⁰#0 @ f².g² -> UnsafeEta +//│ deforest > function g⁰#0 @ f⁰.g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ f².g² -> Pure +//│ deforest > call +⁰@result⁰ @ f⁰.g² -> Pure +//│ deforest > call +⁰@result⁰ @ g¹ -> Pure +//│ deforest > call f¹@result² @ -> UnsafeEta +//│ deforest > call g⁰@result¹ @ f² -> UnsafeEta +//│ deforest > call g⁰@result¹ @ f⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp²) -> @@ -626,9 +626,9 @@ f(AA(AA(0))) fun f(x) = x.AA#aa.AA#aa f(AA(AA(3))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp³) -> @@ -657,67 +657,67 @@ fun outer2(x, y, z) = let p = AA(AA(3)) outer1(p, 1, 2) + outer2(p, 3, 4) + inner(AA(5), 6) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function inner#0 @ inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function outer1#0 @ outer1@outer1 -> UnsafeEta -//│ deforest > function outer1#0 @ outer1@outer1 -> UnsafeEta -//│ deforest > function outer2#0 @ outer2@outer2 -> UnsafeEta -//│ deforest > function outer2#0 @ outer2@outer2 -> UnsafeEta -//│ deforest > call *@result @ inner@inner -> Pure -//│ deforest > call *@result @ inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ inner@inner -> Pure -//│ deforest > call +@result @ inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1 -> Pure -//│ deforest > call +@result @ outer1@outer1 -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2 -> Pure -//│ deforest > call +@result @ outer2@outer2 -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ inner@inner -> Pure -//│ deforest > call -@result @ inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call inner@result @ -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call outer1@result @ -> UnsafeEta -//│ deforest > call outer2@result @ -> UnsafeEta +//│ deforest > function inner⁰#0 @ inner⁵ -> UnsafeEta +//│ deforest > function inner⁰#0 @ inner⁶ -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer1².inner³ -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer1².inner⁴ -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer1⁰.inner³ -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer1⁰.inner⁴ -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer2².inner² -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer2².inner¹ -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer2⁰.inner² -> UnsafeEta +//│ deforest > function inner⁰#0 @ outer2⁰.inner¹ -> UnsafeEta +//│ deforest > function outer1¹#0 @ outer1² -> UnsafeEta +//│ deforest > function outer1¹#0 @ outer1⁰ -> UnsafeEta +//│ deforest > function outer2¹#0 @ outer2² -> UnsafeEta +//│ deforest > function outer2¹#0 @ outer2⁰ -> UnsafeEta +//│ deforest > call *⁰@result⁰ @ inner⁵ -> Pure +//│ deforest > call *⁰@result⁰ @ inner⁶ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1².inner³ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1².inner⁴ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1⁰.inner³ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1⁰.inner⁴ -> Pure +//│ deforest > call *⁰@result⁰ @ outer2².inner² -> Pure +//│ deforest > call *⁰@result⁰ @ outer2².inner¹ -> Pure +//│ deforest > call *⁰@result⁰ @ outer2⁰.inner² -> Pure +//│ deforest > call *⁰@result⁰ @ outer2⁰.inner¹ -> Pure +//│ deforest > call +⁰@result² @ inner⁵ -> Pure +//│ deforest > call +⁰@result² @ inner⁶ -> Pure +//│ deforest > call +⁰@result² @ outer1².inner³ -> Pure +//│ deforest > call +⁰@result² @ outer1².inner⁴ -> Pure +//│ deforest > call +⁰@result² @ outer1⁰.inner³ -> Pure +//│ deforest > call +⁰@result² @ outer1⁰.inner⁴ -> Pure +//│ deforest > call +⁰@result² @ outer2².inner² -> Pure +//│ deforest > call +⁰@result² @ outer2².inner¹ -> Pure +//│ deforest > call +⁰@result² @ outer2⁰.inner² -> Pure +//│ deforest > call +⁰@result² @ outer2⁰.inner¹ -> Pure +//│ deforest > call +⁰@result¹¹ @ -> Pure +//│ deforest > call +⁰@result⁵ @ outer2² -> Pure +//│ deforest > call +⁰@result⁵ @ outer2⁰ -> Pure +//│ deforest > call +⁰@result⁸ @ outer1² -> Pure +//│ deforest > call +⁰@result⁸ @ outer1⁰ -> Pure +//│ deforest > call +⁰@result⁹ @ -> Pure +//│ deforest > call -⁰@result¹ @ inner⁵ -> Pure +//│ deforest > call -⁰@result¹ @ inner⁶ -> Pure +//│ deforest > call -⁰@result¹ @ outer1².inner³ -> Pure +//│ deforest > call -⁰@result¹ @ outer1².inner⁴ -> Pure +//│ deforest > call -⁰@result¹ @ outer1⁰.inner³ -> Pure +//│ deforest > call -⁰@result¹ @ outer1⁰.inner⁴ -> Pure +//│ deforest > call -⁰@result¹ @ outer2².inner² -> Pure +//│ deforest > call -⁰@result¹ @ outer2².inner¹ -> Pure +//│ deforest > call -⁰@result¹ @ outer2⁰.inner² -> Pure +//│ deforest > call -⁰@result¹ @ outer2⁰.inner¹ -> Pure +//│ deforest > call inner⁰@result³ @ outer2² -> UnsafeEta +//│ deforest > call inner⁰@result³ @ outer2⁰ -> UnsafeEta +//│ deforest > call inner⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call inner⁰@result⁴ @ outer2² -> UnsafeEta +//│ deforest > call inner⁰@result⁴ @ outer2⁰ -> UnsafeEta +//│ deforest > call inner⁰@result⁶ @ outer1² -> UnsafeEta +//│ deforest > call inner⁰@result⁶ @ outer1⁰ -> UnsafeEta +//│ deforest > call inner⁰@result⁷ @ outer1² -> UnsafeEta +//│ deforest > call inner⁰@result⁷ @ outer1⁰ -> UnsafeEta +//│ deforest > call outer1¹@result¹³ @ -> UnsafeEta +//│ deforest > call outer2¹@result¹² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(5) -> @@ -733,13 +733,13 @@ fun mapHead(f, x) = if x is AAA(h, t) then f(h) mapHead(x => x, AAA(1, AAA(2, None))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function lambda#0 @ lambda@lambda -> Pure -//│ deforest > function mapHead#0 @ mapHead@mapHead -> UnsafeEta -//│ deforest > function mapHead#0 @ mapHead@mapHead -> UnsafeEta -//│ deforest > call f@result @ mapHead@mapHead -> Pure -//│ deforest > call f@result @ mapHead@mapHead -> UnsafeEta -//│ deforest > call mapHead@result @ -> UnsafeEta +//│ deforest > function lambda⁰#0 @ lambda² -> Pure +//│ deforest > function lambda⁰#0 @ lambda¹ -> Pure +//│ deforest > function mapHead⁰#0 @ mapHead² -> UnsafeEta +//│ deforest > function mapHead⁰#0 @ mapHead¹ -> UnsafeEta +//│ deforest > call f⁰@result⁰ @ mapHead² -> Pure +//│ deforest > call f⁰@result⁰ @ mapHead¹ -> UnsafeEta +//│ deforest > call mapHead⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AAA⁰(1, tmp⁴) -> @@ -757,7 +757,7 @@ if A is k = 3 k + 2 //│ deforest > >>> effect-analysis results >>> -//│ deforest > call +@result @ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -772,12 +772,12 @@ fun test(a) = if a is else 2 test(B) + test(C) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call test⁰@result² @ -> UnsafeEta +//│ deforest > call test⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > C⁰ -> @@ -800,15 +800,15 @@ fun test(x, y, z) = if x is m + n test(AA(1), AA(2), AA(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ test² -> Pure +//│ deforest > call +⁰@result² @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call -⁰@result¹ @ test² -> Pure +//│ deforest > call -⁰@result¹ @ test¹ -> Pure +//│ deforest > call test⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> @@ -831,21 +831,21 @@ fun test(x) = let p = if true then AA(CCC(AA)) else BB(CCC(AA)) in... test(p) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call id@result @ test@test -> UnsafeEta -//│ deforest > call id@result @ test@test -> UnsafeEta -//│ deforest > call t@result @ test@test -> UnsafeEta -//│ deforest > call t@result @ test@test -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result² @ test² -> Pure +//│ deforest > call +⁰@result² @ test¹ -> Pure +//│ deforest > call +⁰@result⁴ @ test² -> Pure +//│ deforest > call +⁰@result⁴ @ test¹ -> Pure +//│ deforest > call -⁰@result³ @ test² -> Pure +//│ deforest > call -⁰@result³ @ test¹ -> Pure +//│ deforest > call -⁰@result⁵ @ test² -> Pure +//│ deforest > call -⁰@result⁵ @ test¹ -> Pure +//│ deforest > call id@result⁰ @ test² -> UnsafeEta +//│ deforest > call id@result⁰ @ test¹ -> UnsafeEta +//│ deforest > call test⁰@result⁶ @ -> UnsafeEta +//│ deforest > call t⁰@result¹ @ test² -> UnsafeEta +//│ deforest > call t⁰@result¹ @ test¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(tmp⁵) -> @@ -875,20 +875,20 @@ fun test(x, y) = let p = if true then AA(CCC) else BB(CCC) in... test(p, id(CCC(123))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call id@result @ -> UnsafeEta -//│ deforest > call t@result @ test@test -> UnsafeEta -//│ deforest > call t@result @ test@test -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result³ @ test² -> Pure +//│ deforest > call +⁰@result³ @ test¹ -> Pure +//│ deforest > call +⁰@result¹ @ test² -> Pure +//│ deforest > call +⁰@result¹ @ test¹ -> Pure +//│ deforest > call -⁰@result² @ test² -> Pure +//│ deforest > call -⁰@result² @ test¹ -> Pure +//│ deforest > call -⁰@result⁴ @ test² -> Pure +//│ deforest > call -⁰@result⁴ @ test¹ -> Pure +//│ deforest > call id@result⁶ @ -> UnsafeEta +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta +//│ deforest > call t⁰@result⁰ @ test² -> UnsafeEta +//│ deforest > call t⁰@result⁰ @ test¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(CCC⁰) -> @@ -907,13 +907,13 @@ fun f(x) = if x is A then 1 f(id(A)) + f(A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call id@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f³ -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call f⁰@result² @ -> UnsafeEta +//│ deforest > call f⁰@result¹ @ -> UnsafeEta +//│ deforest > call id@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -960,12 +960,12 @@ fun g(x) = if x is BB then B f(g(AA(1))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call f²@result⁰ @ -> UnsafeEta +//│ deforest > call g⁰@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -984,9 +984,9 @@ fun f(a, b) = if a is else 0 f(A, B) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > function f#0 @ f@f -> Pure -//│ deforest > call f@result @ -> Pure +//│ deforest > function f²#0 @ f³ -> Pure +//│ deforest > function f²#0 @ f⁴ -> Pure +//│ deforest > call f²@result⁰ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -1008,25 +1008,25 @@ fun c2(x) = if x is A then 0 c1(app(AA)) + c1(AA(2)) + c2(AA(3)) + c2(A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function app#0 @ app@app -> UnsafeEta -//│ deforest > function app#0 @ app@app -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function identity#0 @ identity@identity -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call app@result @ -> UnsafeEta -//│ deforest > call c1@result @ -> UnsafeEta -//│ deforest > call c1@result @ -> UnsafeEta -//│ deforest > call c2@result @ -> UnsafeEta -//│ deforest > call c2@result @ -> UnsafeEta -//│ deforest > call f@result @ app@app -> UnsafeEta -//│ deforest > call f@result @ app@app -> UnsafeEta +//│ deforest > function app⁰#0 @ app² -> UnsafeEta +//│ deforest > function app⁰#0 @ app¹ -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1² -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1³ -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1¹ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2³ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2¹ -> UnsafeEta +//│ deforest > function identity⁰#0 @ identity¹ -> Pure +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁵ @ -> Pure +//│ deforest > call app⁰@result⁸ @ -> UnsafeEta +//│ deforest > call c1⁰@result⁶ @ -> UnsafeEta +//│ deforest > call c1⁰@result⁷ @ -> UnsafeEta +//│ deforest > call c2⁰@result² @ -> UnsafeEta +//│ deforest > call c2⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f²@result⁰ @ app² -> UnsafeEta +//│ deforest > call f²@result⁰ @ app¹ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -1051,28 +1051,28 @@ fun c(x) = if x is print(c(p(true)) + c(p(false))) c(B) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call Error@result @ c@c -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call print@result @ -> UnsafeEta +//│ deforest > function c¹#0 @ c² -> UnsafeEta +//│ deforest > function c¹#0 @ c³ -> UnsafeEta +//│ deforest > function c¹#0 @ c⁴ -> UnsafeEta +//│ deforest > function c¹#0 @ c⁵ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p³ -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call Error@result¹ @ c² -> UnsafeEta +//│ deforest > call Error@result¹ @ c³ -> UnsafeEta +//│ deforest > call Error@result¹ @ c⁴ -> UnsafeEta +//│ deforest > call Error@result¹ @ c⁵ -> UnsafeEta +//│ deforest > call Error@result⁰ @ c² -> UnsafeEta +//│ deforest > call Error@result⁰ @ c³ -> UnsafeEta +//│ deforest > call Error@result⁰ @ c⁴ -> UnsafeEta +//│ deforest > call Error@result⁰ @ c⁵ -> UnsafeEta +//│ deforest > call c¹@result² @ -> UnsafeEta +//│ deforest > call c¹@result⁵ @ -> UnsafeEta +//│ deforest > call c¹@result⁷ @ -> UnsafeEta +//│ deforest > call print@result³ @ -> UnsafeEta +//│ deforest > call p⁰@result⁶ @ -> UnsafeEta +//│ deforest > call p⁰@result⁸ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -1107,11 +1107,11 @@ fun f(a, b) = if a is AA(x) then x + b.BB#bb f(AA(1), BB(2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call +@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ f³ -> Pure +//│ deforest > call +⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call f²@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(2) -> @@ -1129,13 +1129,13 @@ fun g(k, x) = if k is A then x.AA#aa + x.AA#aa + x.AA#aa g(A, AA(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call +@result @ g@g -> Pure -//│ deforest > call g@result @ -> UnsafeEta +//│ deforest > function g⁰#0 @ g² -> UnsafeEta +//│ deforest > function g⁰#0 @ g¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ g² -> Pure +//│ deforest > call +⁰@result¹ @ g¹ -> Pure +//│ deforest > call +⁰@result⁰ @ g² -> Pure +//│ deforest > call +⁰@result⁰ @ g¹ -> Pure +//│ deforest > call g⁰@result² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -1164,81 +1164,81 @@ fun outer2(x, y)(z) = let p = AA(AA(3)) outer1(p)(1, 2) + outer2(p, 3)(4) + inner(AA(5))(6) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function inner#0 @ inner@inner -> Pure -//│ deforest > function inner#0 @ inner@inner -> Pure -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure -//│ deforest > function inner#0 @ outer1@outer1.inner@inner -> Pure -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure -//│ deforest > function inner#0 @ outer2@outer2.inner@inner -> Pure -//│ deforest > function inner#1 @ inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer1@outer1.inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function inner#1 @ outer2@outer2.inner@inner -> UnsafeEta -//│ deforest > function outer1#0 @ outer1@outer1 -> Pure -//│ deforest > function outer1#0 @ outer1@outer1 -> Pure -//│ deforest > function outer1#1 @ outer1@outer1 -> UnsafeEta -//│ deforest > function outer1#1 @ outer1@outer1 -> UnsafeEta -//│ deforest > function outer2#0 @ outer2@outer2 -> Pure -//│ deforest > function outer2#0 @ outer2@outer2 -> Pure -//│ deforest > function outer2#1 @ outer2@outer2 -> UnsafeEta -//│ deforest > function outer2#1 @ outer2@outer2 -> UnsafeEta -//│ deforest > call *@result @ inner@inner -> Pure -//│ deforest > call *@result @ inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call *@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ inner@inner -> Pure -//│ deforest > call +@result @ inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1 -> Pure -//│ deforest > call +@result @ outer1@outer1 -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2 -> Pure -//│ deforest > call +@result @ outer2@outer2 -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call +@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ inner@inner -> Pure -//│ deforest > call -@result @ inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer1@outer1.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call -@result @ outer2@outer2.inner@inner -> Pure -//│ deforest > call inner@result @ -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer1@outer1 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call inner@result @ outer2@outer2 -> UnsafeEta -//│ deforest > call outer1@result @ -> UnsafeEta -//│ deforest > call outer2@result @ -> UnsafeEta +//│ deforest > function inner⁰#0 @ inner⁵ -> Pure +//│ deforest > function inner⁰#0 @ inner⁶ -> Pure +//│ deforest > function inner⁰#0 @ outer1².inner³ -> Pure +//│ deforest > function inner⁰#0 @ outer1².inner⁴ -> Pure +//│ deforest > function inner⁰#0 @ outer1⁰.inner³ -> Pure +//│ deforest > function inner⁰#0 @ outer1⁰.inner⁴ -> Pure +//│ deforest > function inner⁰#0 @ outer2².inner² -> Pure +//│ deforest > function inner⁰#0 @ outer2².inner¹ -> Pure +//│ deforest > function inner⁰#0 @ outer2⁰.inner² -> Pure +//│ deforest > function inner⁰#0 @ outer2⁰.inner¹ -> Pure +//│ deforest > function inner⁰#1 @ inner⁵ -> UnsafeEta +//│ deforest > function inner⁰#1 @ inner⁶ -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer1².inner³ -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer1².inner⁴ -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer1⁰.inner³ -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer1⁰.inner⁴ -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer2².inner² -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer2².inner¹ -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer2⁰.inner² -> UnsafeEta +//│ deforest > function inner⁰#1 @ outer2⁰.inner¹ -> UnsafeEta +//│ deforest > function outer1¹#0 @ outer1² -> Pure +//│ deforest > function outer1¹#0 @ outer1⁰ -> Pure +//│ deforest > function outer1¹#1 @ outer1² -> UnsafeEta +//│ deforest > function outer1¹#1 @ outer1⁰ -> UnsafeEta +//│ deforest > function outer2¹#0 @ outer2² -> Pure +//│ deforest > function outer2¹#0 @ outer2⁰ -> Pure +//│ deforest > function outer2¹#1 @ outer2² -> UnsafeEta +//│ deforest > function outer2¹#1 @ outer2⁰ -> UnsafeEta +//│ deforest > call *⁰@result⁰ @ inner⁵ -> Pure +//│ deforest > call *⁰@result⁰ @ inner⁶ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1².inner³ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1².inner⁴ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1⁰.inner³ -> Pure +//│ deforest > call *⁰@result⁰ @ outer1⁰.inner⁴ -> Pure +//│ deforest > call *⁰@result⁰ @ outer2².inner² -> Pure +//│ deforest > call *⁰@result⁰ @ outer2².inner¹ -> Pure +//│ deforest > call *⁰@result⁰ @ outer2⁰.inner² -> Pure +//│ deforest > call *⁰@result⁰ @ outer2⁰.inner¹ -> Pure +//│ deforest > call +⁰@result² @ inner⁵ -> Pure +//│ deforest > call +⁰@result² @ inner⁶ -> Pure +//│ deforest > call +⁰@result² @ outer1².inner³ -> Pure +//│ deforest > call +⁰@result² @ outer1².inner⁴ -> Pure +//│ deforest > call +⁰@result² @ outer1⁰.inner³ -> Pure +//│ deforest > call +⁰@result² @ outer1⁰.inner⁴ -> Pure +//│ deforest > call +⁰@result² @ outer2².inner² -> Pure +//│ deforest > call +⁰@result² @ outer2².inner¹ -> Pure +//│ deforest > call +⁰@result² @ outer2⁰.inner² -> Pure +//│ deforest > call +⁰@result² @ outer2⁰.inner¹ -> Pure +//│ deforest > call +⁰@result¹¹ @ -> Pure +//│ deforest > call +⁰@result⁵ @ outer2² -> Pure +//│ deforest > call +⁰@result⁵ @ outer2⁰ -> Pure +//│ deforest > call +⁰@result⁸ @ outer1² -> Pure +//│ deforest > call +⁰@result⁸ @ outer1⁰ -> Pure +//│ deforest > call +⁰@result⁹ @ -> Pure +//│ deforest > call -⁰@result¹ @ inner⁵ -> Pure +//│ deforest > call -⁰@result¹ @ inner⁶ -> Pure +//│ deforest > call -⁰@result¹ @ outer1².inner³ -> Pure +//│ deforest > call -⁰@result¹ @ outer1².inner⁴ -> Pure +//│ deforest > call -⁰@result¹ @ outer1⁰.inner³ -> Pure +//│ deforest > call -⁰@result¹ @ outer1⁰.inner⁴ -> Pure +//│ deforest > call -⁰@result¹ @ outer2².inner² -> Pure +//│ deforest > call -⁰@result¹ @ outer2².inner¹ -> Pure +//│ deforest > call -⁰@result¹ @ outer2⁰.inner² -> Pure +//│ deforest > call -⁰@result¹ @ outer2⁰.inner¹ -> Pure +//│ deforest > call inner⁰@result³ @ outer2² -> UnsafeEta +//│ deforest > call inner⁰@result³ @ outer2⁰ -> UnsafeEta +//│ deforest > call inner⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call inner⁰@result⁴ @ outer2² -> UnsafeEta +//│ deforest > call inner⁰@result⁴ @ outer2⁰ -> UnsafeEta +//│ deforest > call inner⁰@result⁶ @ outer1² -> UnsafeEta +//│ deforest > call inner⁰@result⁶ @ outer1⁰ -> UnsafeEta +//│ deforest > call inner⁰@result⁷ @ outer1² -> UnsafeEta +//│ deforest > call inner⁰@result⁷ @ outer1⁰ -> UnsafeEta +//│ deforest > call outer1¹@result¹³ @ -> UnsafeEta +//│ deforest > call outer2¹@result¹² @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(5) -> @@ -1258,9 +1258,9 @@ fun f(x) = if x is AA then x.AA#aa.AA#aa f(AA(AA(3))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call f²@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(tmp⁷) -> @@ -1279,18 +1279,18 @@ fun f1(a1) = if a1 is AA then 1 fun f2(a2) = if a2 is AA then 2 f1(id(AA(1))) + f2(id(AA(2))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function id#0 @ id@id -> Pure -//│ deforest > function id#0 @ id@id -> Pure -//│ deforest > function id#0 @ id@id -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call id@result @ -> Pure -//│ deforest > call id@result @ -> Pure +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function id¹#0 @ id² -> Pure +//│ deforest > function id¹#0 @ id³ -> Pure +//│ deforest > function id¹#0 @ id⁴ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call f1⁰@result³ @ -> UnsafeEta +//│ deforest > call f2⁰@result¹ @ -> UnsafeEta +//│ deforest > call id¹@result² @ -> Pure +//│ deforest > call id¹@result⁴ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> @@ -1310,9 +1310,9 @@ fun c1(x) = if x is Nil then 0 c1(1 :: Nil) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > call c1@result @ -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1² -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1¹ -> UnsafeEta +//│ deforest > call c1⁰@result⁰ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(1, Nil⁰) -> @@ -1338,23 +1338,23 @@ fun apply(f) = f(AA(inner)) apply(f) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function apply#0 @ apply@apply -> UnsafeEta -//│ deforest > function apply#0 @ apply@apply -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function g1#0 @ f@f.g1@g1 -> UnsafeEta -//│ deforest > function g1#0 @ f@f.g1@g1 -> UnsafeEta -//│ deforest > function g1#0 @ g1@g1 -> UnsafeEta -//│ deforest > function g2#0 @ f@f.g2@g2 -> UnsafeEta -//│ deforest > function g2#0 @ f@f.g2@g2 -> UnsafeEta -//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta -//│ deforest > call apply@result @ -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta -//│ deforest > call f@result @ apply@apply -> UnsafeEta -//│ deforest > call g1@result @ f@f -> UnsafeEta -//│ deforest > call g1@result @ f@f -> UnsafeEta -//│ deforest > call g2@result @ f@f -> UnsafeEta -//│ deforest > call g2@result @ f@f -> UnsafeEta +//│ deforest > function apply⁰#0 @ apply² -> UnsafeEta +//│ deforest > function apply⁰#0 @ apply¹ -> UnsafeEta +//│ deforest > function f³#0 @ f² -> UnsafeEta +//│ deforest > function f³#0 @ f⁴ -> UnsafeEta +//│ deforest > function g1⁰#0 @ f².g1² -> UnsafeEta +//│ deforest > function g1⁰#0 @ f⁴.g1² -> UnsafeEta +//│ deforest > function g1⁰#0 @ g1¹ -> UnsafeEta +//│ deforest > function g2⁰#0 @ f².g2² -> UnsafeEta +//│ deforest > function g2⁰#0 @ f⁴.g2² -> UnsafeEta +//│ deforest > function g2⁰#0 @ g2¹ -> UnsafeEta +//│ deforest > call apply⁰@result³ @ -> UnsafeEta +//│ deforest > call f⁵@result⁰ @ apply² -> UnsafeEta +//│ deforest > call f⁵@result⁰ @ apply¹ -> UnsafeEta +//│ deforest > call g1⁰@result¹ @ f² -> UnsafeEta +//│ deforest > call g1⁰@result¹ @ f⁴ -> UnsafeEta +//│ deforest > call g2⁰@result² @ f² -> UnsafeEta +//│ deforest > call g2⁰@result² @ f⁴ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(inner⁰) -> @@ -1374,34 +1374,34 @@ fun f1(a1) = if a1 is AA then 1 fun f2(a2) = if a2 is AA then 2 f1(wrap(1)) + f2(wrap(2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap1@wrap1.p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap@wrap.wrap1@wrap1.p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap@wrap.wrap1@wrap1.p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap@wrap.wrap1@wrap1.p@p -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > function wrap1#0 @ wrap1@wrap1 -> UnsafeEta -//│ deforest > function wrap1#0 @ wrap@wrap.wrap1@wrap1 -> UnsafeEta -//│ deforest > function wrap1#0 @ wrap@wrap.wrap1@wrap1 -> UnsafeEta -//│ deforest > function wrap1#0 @ wrap@wrap.wrap1@wrap1 -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call p@result @ wrap1@wrap1 -> UnsafeEta -//│ deforest > call p@result @ wrap@wrap.wrap1@wrap1 -> UnsafeEta -//│ deforest > call p@result @ wrap@wrap.wrap1@wrap1 -> UnsafeEta -//│ deforest > call p@result @ wrap@wrap.wrap1@wrap1 -> UnsafeEta -//│ deforest > call wrap1@result @ wrap@wrap -> UnsafeEta -//│ deforest > call wrap1@result @ wrap@wrap -> UnsafeEta -//│ deforest > call wrap1@result @ wrap@wrap -> UnsafeEta -//│ deforest > call wrap@result @ -> UnsafeEta -//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap1².p¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap².wrap1¹.p¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap³.wrap1¹.p¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap⁰.wrap1¹.p¹ -> UnsafeEta +//│ deforest > function wrap1⁰#0 @ wrap1² -> UnsafeEta +//│ deforest > function wrap1⁰#0 @ wrap².wrap1¹ -> UnsafeEta +//│ deforest > function wrap1⁰#0 @ wrap³.wrap1¹ -> UnsafeEta +//│ deforest > function wrap1⁰#0 @ wrap⁰.wrap1¹ -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap² -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap³ -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap⁰ -> UnsafeEta +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call f1⁰@result⁵ @ -> UnsafeEta +//│ deforest > call f2⁰@result³ @ -> UnsafeEta +//│ deforest > call p⁰@result⁰ @ wrap1² -> UnsafeEta +//│ deforest > call p⁰@result⁰ @ wrap².wrap1¹ -> UnsafeEta +//│ deforest > call p⁰@result⁰ @ wrap³.wrap1¹ -> UnsafeEta +//│ deforest > call p⁰@result⁰ @ wrap⁰.wrap1¹ -> UnsafeEta +//│ deforest > call wrap1⁰@result¹ @ wrap² -> UnsafeEta +//│ deforest > call wrap1⁰@result¹ @ wrap³ -> UnsafeEta +//│ deforest > call wrap1⁰@result¹ @ wrap⁰ -> UnsafeEta +//│ deforest > call wrap¹@result⁴ @ -> UnsafeEta +//│ deforest > call wrap¹@result⁶ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³¹) -> @@ -1418,28 +1418,28 @@ fun p2(x) = if x == 0 then AA(x) else p1(x - 1) fun c(a) = if a is AA(x) then x c(p1(3)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function c#0 @ c@c -> UnsafeEta -//│ deforest > function p1#0 @ p1@p1 -> UnsafeEta -//│ deforest > function p1#0 @ p1@p1 -> UnsafeEta -//│ deforest > function p1#0 @ p2@p2 -> UnsafeEta -//│ deforest > function p2#0 @ p1@p1 -> UnsafeEta -//│ deforest > function p2#0 @ p1@p1 -> UnsafeEta -//│ deforest > function p2#0 @ p2@p2 -> UnsafeEta -//│ deforest > call -@result @ p1@p1 -> Pure -//│ deforest > call -@result @ p1@p1 -> Pure -//│ deforest > call -@result @ p2@p2 -> Pure -//│ deforest > call c@result @ -> UnsafeEta -//│ deforest > call equals@result @ p1@p1 -> UnsafeEta -//│ deforest > call equals@result @ p1@p1 -> UnsafeEta -//│ deforest > call equals@result @ p2@p2 -> UnsafeEta -//│ deforest > call p1@result @ -> UnsafeEta -//│ deforest > call p1@result @ p1@p1 -> UnsafeEta -//│ deforest > call p1@result @ p1@p1 -> UnsafeEta -//│ deforest > call p1@result @ p2@p2 -> UnsafeEta -//│ deforest > call p2@result @ p1@p1 -> UnsafeEta -//│ deforest > call p2@result @ p1@p1 -> UnsafeEta -//│ deforest > call p2@result @ p2@p2 -> UnsafeEta +//│ deforest > function c¹#0 @ c² -> UnsafeEta +//│ deforest > function c¹#0 @ c³ -> UnsafeEta +//│ deforest > function p1⁰#0 @ p1² -> UnsafeEta +//│ deforest > function p1⁰#0 @ p1¹ -> UnsafeEta +//│ deforest > function p1⁰#0 @ p2⁰ -> UnsafeEta +//│ deforest > function p2¹#0 @ p1² -> UnsafeEta +//│ deforest > function p2¹#0 @ p1¹ -> UnsafeEta +//│ deforest > function p2¹#0 @ p2⁰ -> UnsafeEta +//│ deforest > call -⁰@result² @ p1² -> Pure +//│ deforest > call -⁰@result² @ p1¹ -> Pure +//│ deforest > call -⁰@result² @ p2⁰ -> Pure +//│ deforest > call c¹@result⁴ @ -> UnsafeEta +//│ deforest > call equals@result¹ @ p1² -> UnsafeEta +//│ deforest > call equals@result¹ @ p1¹ -> UnsafeEta +//│ deforest > call equals@result¹ @ p2⁰ -> UnsafeEta +//│ deforest > call p1⁰@result³ @ p1² -> UnsafeEta +//│ deforest > call p1⁰@result³ @ p1¹ -> UnsafeEta +//│ deforest > call p1⁰@result³ @ p2⁰ -> UnsafeEta +//│ deforest > call p1⁰@result⁵ @ -> UnsafeEta +//│ deforest > call p2¹@result⁰ @ p1² -> UnsafeEta +//│ deforest > call p2¹@result⁰ @ p1¹ -> UnsafeEta +//│ deforest > call p2¹@result⁰ @ p2⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³²) -> @@ -1464,36 +1464,36 @@ fun g(b) = C [f(3), g(true)] //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ g@g -> UnsafeEta -//│ deforest > function f#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ g@g -> Pure -//│ deforest > call -@result @ g@g -> Pure -//│ deforest > call <@result @ f@f -> Pure -//│ deforest > call <@result @ f@f -> Pure -//│ deforest > call <@result @ g@g -> Pure -//│ deforest > call <@result @ g@g -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call g@result @ -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ g@g -> UnsafeEta -//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > function f²#0 @ g² -> UnsafeEta +//│ deforest > function f²#0 @ g⁰ -> UnsafeEta +//│ deforest > function g¹#0 @ f³ -> UnsafeEta +//│ deforest > function g¹#0 @ f⁴ -> UnsafeEta +//│ deforest > function g¹#0 @ g² -> UnsafeEta +//│ deforest > function g¹#0 @ g⁰ -> UnsafeEta +//│ deforest > call -⁰@result² @ f³ -> Pure +//│ deforest > call -⁰@result² @ f⁴ -> Pure +//│ deforest > call -⁰@result² @ g² -> Pure +//│ deforest > call -⁰@result² @ g⁰ -> Pure +//│ deforest > call <⁰@result¹ @ f³ -> Pure +//│ deforest > call <⁰@result¹ @ f⁴ -> Pure +//│ deforest > call <⁰@result¹ @ g² -> Pure +//│ deforest > call <⁰@result¹ @ g⁰ -> Pure +//│ deforest > call f²@result³ @ f³ -> UnsafeEta +//│ deforest > call f²@result³ @ f⁴ -> UnsafeEta +//│ deforest > call f²@result³ @ g² -> UnsafeEta +//│ deforest > call f²@result³ @ g⁰ -> UnsafeEta +//│ deforest > call f²@result⁴ @ f³ -> UnsafeEta +//│ deforest > call f²@result⁴ @ f⁴ -> UnsafeEta +//│ deforest > call f²@result⁴ @ g² -> UnsafeEta +//│ deforest > call f²@result⁴ @ g⁰ -> UnsafeEta +//│ deforest > call f²@result⁶ @ -> UnsafeEta +//│ deforest > call g¹@result⁰ @ f³ -> UnsafeEta +//│ deforest > call g¹@result⁰ @ f⁴ -> UnsafeEta +//│ deforest > call g¹@result⁰ @ g² -> UnsafeEta +//│ deforest > call g¹@result⁰ @ g⁰ -> UnsafeEta +//│ deforest > call g¹@result⁵ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > BB⁰(0) -> @@ -1530,19 +1530,19 @@ fun f(ls) = if ls is [] then h(3) f([]) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function h#0 @ f@f -> UnsafeEta -//│ deforest > function h#0 @ f@f -> UnsafeEta -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call >@result @ f@f -> Pure -//│ deforest > call >@result @ f@f -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta -//│ deforest > call h@result @ f@f -> UnsafeEta +//│ deforest > function f³#0 @ f² -> UnsafeEta +//│ deforest > function f³#0 @ f⁴ -> UnsafeEta +//│ deforest > function h¹#0 @ f² -> UnsafeEta +//│ deforest > function h¹#0 @ f⁴ -> UnsafeEta +//│ deforest > call -⁰@result¹ @ f² -> Pure +//│ deforest > call -⁰@result¹ @ f⁴ -> Pure +//│ deforest > call >⁰@result⁰ @ f² -> Pure +//│ deforest > call >⁰@result⁰ @ f⁴ -> Pure +//│ deforest > call f³@result⁴ @ -> UnsafeEta +//│ deforest > call h¹@result² @ f² -> UnsafeEta +//│ deforest > call h¹@result² @ f⁴ -> UnsafeEta +//│ deforest > call h¹@result³ @ f² -> UnsafeEta +//│ deforest > call h¹@result³ @ f⁴ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > [] -> @@ -1556,11 +1556,11 @@ fun f(x, b) = if x is Nil then if b then f(Nil, false) else 0 f(Nil, false) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > call f²@result¹ @ -> UnsafeEta +//│ deforest > call f²@result⁰ @ f³ -> UnsafeEta +//│ deforest > call f²@result⁰ @ f⁴ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -1581,15 +1581,15 @@ fun test() = a + b test() + test() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call test⁰@result² @ -> UnsafeEta +//│ deforest > call test⁰@result³ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -1602,18 +1602,18 @@ fun c1(x) = if x is AA then 1 fun c2(x) = if x is AA then 2 c1(p(1)) + c2(p(2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c1#0 @ c1@c1 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function c2#0 @ c2@c2 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call c1@result @ -> UnsafeEta -//│ deforest > call c2@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1² -> UnsafeEta +//│ deforest > function c1⁰#0 @ c1¹ -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2² -> UnsafeEta +//│ deforest > function c2⁰#0 @ c2¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p³ -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call c1⁰@result³ @ -> UnsafeEta +//│ deforest > call c2⁰@result¹ @ -> UnsafeEta +//│ deforest > call p⁰@result² @ -> UnsafeEta +//│ deforest > call p⁰@result⁴ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(3) -> @@ -1633,36 +1633,36 @@ fun f4(a4) = if a4 is AA(aa) then aa fun f5(a5) = if a5 is AA(aa) then aa f1(p(1)) + f2(p(2)) + f3(p(3)) + f4(p(4)) + f5(p(5)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta -//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta -//│ deforest > function f5#0 @ f5@f5 -> UnsafeEta -//│ deforest > function f5#0 @ f5@f5 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call f3@result @ -> UnsafeEta -//│ deforest > call f4@result @ -> UnsafeEta -//│ deforest > call f5@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3² -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3¹ -> UnsafeEta +//│ deforest > function f4⁰#0 @ f4² -> UnsafeEta +//│ deforest > function f4⁰#0 @ f4¹ -> UnsafeEta +//│ deforest > function f5⁰#0 @ f5² -> UnsafeEta +//│ deforest > function f5⁰#0 @ f5¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p² -> UnsafeEta +//│ deforest > function p⁰#0 @ p³ -> UnsafeEta +//│ deforest > function p⁰#0 @ p¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p⁴ -> UnsafeEta +//│ deforest > function p⁰#0 @ p⁵ -> UnsafeEta +//│ deforest > function p⁰#0 @ p⁶ -> UnsafeEta +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call +⁰@result⁶ @ -> Pure +//│ deforest > call +⁰@result⁹ @ -> Pure +//│ deforest > call f1⁰@result¹² @ -> UnsafeEta +//│ deforest > call f2⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call f3⁰@result⁷ @ -> UnsafeEta +//│ deforest > call f4⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f5⁰@result¹ @ -> UnsafeEta +//│ deforest > call p⁰@result² @ -> UnsafeEta +//│ deforest > call p⁰@result¹³ @ -> UnsafeEta +//│ deforest > call p⁰@result¹¹ @ -> UnsafeEta +//│ deforest > call p⁰@result⁵ @ -> UnsafeEta +//│ deforest > call p⁰@result⁸ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁶) -> @@ -1706,61 +1706,61 @@ fun f4(ls4) = if ls4 is Nil then 5 f1(to(4)) + f2(to(5)) + f3(to(6)) + f4(to(7)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta -//│ deforest > function f4#0 @ f4@f4 -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > function to#0 @ to@to -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f3@f3 -> Pure -//│ deforest > call +@result @ f3@f3 -> Pure -//│ deforest > call +@result @ f4@f4 -> Pure -//│ deforest > call +@result @ f4@f4 -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call -@result @ to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call >@result @ to@to -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f1@result @ f1@f1 -> UnsafeEta -//│ deforest > call f1@result @ f1@f1 -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call f2@result @ f2@f2 -> UnsafeEta -//│ deforest > call f2@result @ f2@f2 -> UnsafeEta -//│ deforest > call f3@result @ -> UnsafeEta -//│ deforest > call f3@result @ f3@f3 -> UnsafeEta -//│ deforest > call f3@result @ f3@f3 -> UnsafeEta -//│ deforest > call f4@result @ -> UnsafeEta -//│ deforest > call f4@result @ f4@f4 -> UnsafeEta -//│ deforest > call f4@result @ f4@f4 -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta -//│ deforest > call to@result @ to@to -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3² -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3¹ -> UnsafeEta +//│ deforest > function f4⁰#0 @ f4² -> UnsafeEta +//│ deforest > function f4⁰#0 @ f4¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ to² -> UnsafeEta +//│ deforest > function to⁰#0 @ to³ -> UnsafeEta +//│ deforest > function to⁰#0 @ to¹ -> UnsafeEta +//│ deforest > function to⁰#0 @ to⁴ -> UnsafeEta +//│ deforest > function to⁰#0 @ to⁵ -> UnsafeEta +//│ deforest > call +⁰@result³ @ f3² -> Pure +//│ deforest > call +⁰@result³ @ f3¹ -> Pure +//│ deforest > call +⁰@result¹ @ f4² -> Pure +//│ deforest > call +⁰@result¹ @ f4¹ -> Pure +//│ deforest > call +⁰@result¹¹ @ -> Pure +//│ deforest > call +⁰@result¹⁴ @ -> Pure +//│ deforest > call +⁰@result¹⁷ @ -> Pure +//│ deforest > call +⁰@result⁵ @ f2² -> Pure +//│ deforest > call +⁰@result⁵ @ f2¹ -> Pure +//│ deforest > call +⁰@result⁷ @ f1² -> Pure +//│ deforest > call +⁰@result⁷ @ f1¹ -> Pure +//│ deforest > call -⁰@result⁹ @ to² -> Pure +//│ deforest > call -⁰@result⁹ @ to³ -> Pure +//│ deforest > call -⁰@result⁹ @ to¹ -> Pure +//│ deforest > call -⁰@result⁹ @ to⁴ -> Pure +//│ deforest > call -⁰@result⁹ @ to⁵ -> Pure +//│ deforest > call >⁰@result⁸ @ to² -> Pure +//│ deforest > call >⁰@result⁸ @ to³ -> Pure +//│ deforest > call >⁰@result⁸ @ to¹ -> Pure +//│ deforest > call >⁰@result⁸ @ to⁴ -> Pure +//│ deforest > call >⁰@result⁸ @ to⁵ -> Pure +//│ deforest > call f1⁰@result²⁰ @ -> UnsafeEta +//│ deforest > call f1⁰@result⁶ @ f1² -> UnsafeEta +//│ deforest > call f1⁰@result⁶ @ f1¹ -> UnsafeEta +//│ deforest > call f2⁰@result¹⁸ @ -> UnsafeEta +//│ deforest > call f2⁰@result⁴ @ f2² -> UnsafeEta +//│ deforest > call f2⁰@result⁴ @ f2¹ -> UnsafeEta +//│ deforest > call f3⁰@result² @ f3² -> UnsafeEta +//│ deforest > call f3⁰@result² @ f3¹ -> UnsafeEta +//│ deforest > call f3⁰@result¹⁵ @ -> UnsafeEta +//│ deforest > call f4⁰@result¹² @ -> UnsafeEta +//│ deforest > call f4⁰@result⁰ @ f4² -> UnsafeEta +//│ deforest > call f4⁰@result⁰ @ f4¹ -> UnsafeEta +//│ deforest > call to⁰@result²¹ @ -> UnsafeEta +//│ deforest > call to⁰@result¹³ @ -> UnsafeEta +//│ deforest > call to⁰@result¹⁰ @ to² -> UnsafeEta +//│ deforest > call to⁰@result¹⁰ @ to³ -> UnsafeEta +//│ deforest > call to⁰@result¹⁰ @ to¹ -> UnsafeEta +//│ deforest > call to⁰@result¹⁰ @ to⁴ -> UnsafeEta +//│ deforest > call to⁰@result¹⁰ @ to⁵ -> UnsafeEta +//│ deforest > call to⁰@result¹⁶ @ -> UnsafeEta +//│ deforest > call to⁰@result¹⁹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Cons⁰(n⁰, tmp⁸) -> @@ -1802,49 +1802,49 @@ fun f1(p) = if p is AA(a) then a + 1 fun f2(p) = if p is AA(b) then b + 2 f1(wrap(true)) + f2(g2(false)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function g1#0 @ g1@g1 -> UnsafeEta -//│ deforest > function g1#0 @ wrap@wrap.g1@g1 -> UnsafeEta -//│ deforest > function g1#0 @ wrap@wrap.g1@g1 -> UnsafeEta -//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta -//│ deforest > function g2#0 @ g2@g2 -> UnsafeEta -//│ deforest > function p#0 @ g1@g1.p@p -> UnsafeEta -//│ deforest > function p#0 @ g1@g1.p@p -> UnsafeEta -//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta -//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta -//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta -//│ deforest > function p#0 @ g2@g2.p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta -//│ deforest > function p#0 @ wrap@wrap.g1@g1.p@p -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call g1@result @ wrap@wrap -> UnsafeEta -//│ deforest > call g1@result @ wrap@wrap -> UnsafeEta -//│ deforest > call g2@result @ -> UnsafeEta -//│ deforest > call p@result @ g1@g1 -> UnsafeEta -//│ deforest > call p@result @ g1@g1 -> UnsafeEta -//│ deforest > call p@result @ g2@g2 -> UnsafeEta -//│ deforest > call p@result @ g2@g2 -> UnsafeEta -//│ deforest > call p@result @ g2@g2 -> UnsafeEta -//│ deforest > call p@result @ g2@g2 -> UnsafeEta -//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta -//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta -//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta -//│ deforest > call p@result @ wrap@wrap.g1@g1 -> UnsafeEta -//│ deforest > call wrap@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function g1⁰#0 @ g1² -> UnsafeEta +//│ deforest > function g1⁰#0 @ wrap².g1¹ -> UnsafeEta +//│ deforest > function g1⁰#0 @ wrap⁰.g1¹ -> UnsafeEta +//│ deforest > function g2¹#0 @ g2² -> UnsafeEta +//│ deforest > function g2¹#0 @ g2⁰ -> UnsafeEta +//│ deforest > function p⁰#0 @ g1².p³ -> UnsafeEta +//│ deforest > function p⁰#0 @ g1².p⁴ -> UnsafeEta +//│ deforest > function p⁰#0 @ g2².p² -> UnsafeEta +//│ deforest > function p⁰#0 @ g2².p¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ g2⁰.p² -> UnsafeEta +//│ deforest > function p⁰#0 @ g2⁰.p¹ -> UnsafeEta +//│ deforest > function p⁰#0 @ p⁵ -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap².g1¹.p³ -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap².g1¹.p⁴ -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap⁰.g1¹.p³ -> UnsafeEta +//│ deforest > function p⁰#0 @ wrap⁰.g1¹.p⁴ -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap² -> UnsafeEta +//│ deforest > function wrap¹#0 @ wrap⁰ -> UnsafeEta +//│ deforest > call +⁰@result¹ @ f1² -> Pure +//│ deforest > call +⁰@result¹ @ f1¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f2² -> Pure +//│ deforest > call +⁰@result⁰ @ f2¹ -> Pure +//│ deforest > call +⁰@result⁷ @ -> Pure +//│ deforest > call f1⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call f2⁰@result⁸ @ -> UnsafeEta +//│ deforest > call g1⁰@result⁶ @ wrap² -> UnsafeEta +//│ deforest > call g1⁰@result⁶ @ wrap⁰ -> UnsafeEta +//│ deforest > call g2¹@result⁹ @ -> UnsafeEta +//│ deforest > call p⁰@result² @ g2² -> UnsafeEta +//│ deforest > call p⁰@result² @ g2⁰ -> UnsafeEta +//│ deforest > call p⁰@result³ @ g2² -> UnsafeEta +//│ deforest > call p⁰@result³ @ g2⁰ -> UnsafeEta +//│ deforest > call p⁰@result⁴ @ g1² -> UnsafeEta +//│ deforest > call p⁰@result⁴ @ wrap².g1¹ -> UnsafeEta +//│ deforest > call p⁰@result⁴ @ wrap⁰.g1¹ -> UnsafeEta +//│ deforest > call p⁰@result⁵ @ g1² -> UnsafeEta +//│ deforest > call p⁰@result⁵ @ wrap².g1¹ -> UnsafeEta +//│ deforest > call p⁰@result⁵ @ wrap⁰.g1¹ -> UnsafeEta +//│ deforest > call wrap¹@result¹¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁷) -> @@ -1872,28 +1872,28 @@ fun f2(p) = if p is AA(b) then b + 2 fun f3(p) = if p is AA(c) then c + 3 f1(one) + f2(one) + f3(two) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > function f3#0 @ f3@f3 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f3@f3 -> Pure -//│ deforest > call +@result @ f3@f3 -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call f3@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3² -> UnsafeEta +//│ deforest > function f3⁰#0 @ f3¹ -> UnsafeEta +//│ deforest > function p²#0 @ p³ -> UnsafeEta +//│ deforest > function p²#0 @ p⁴ -> UnsafeEta +//│ deforest > function p²#0 @ p⁵ -> UnsafeEta +//│ deforest > call +⁰@result² @ f1² -> Pure +//│ deforest > call +⁰@result² @ f1¹ -> Pure +//│ deforest > call +⁰@result³ @ -> Pure +//│ deforest > call +⁰@result¹ @ f2² -> Pure +//│ deforest > call +⁰@result¹ @ f2¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f3² -> Pure +//│ deforest > call +⁰@result⁰ @ f3¹ -> Pure +//│ deforest > call +⁰@result⁵ @ -> Pure +//│ deforest > call f1⁰@result⁷ @ -> UnsafeEta +//│ deforest > call f2⁰@result⁶ @ -> UnsafeEta +//│ deforest > call f3⁰@result⁴ @ -> UnsafeEta +//│ deforest > call p²@result⁸ @ -> UnsafeEta +//│ deforest > call p²@result⁹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁸) -> @@ -1909,20 +1909,20 @@ fun f1(a) = if a is AA(i) then i fun f2(a) = if a is AA(i) then i + 1 f1(id(AA(1))) + f2(id(AA(2))) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function id#0 @ id@id -> Pure -//│ deforest > function id#0 @ id@id -> Pure -//│ deforest > function id#0 @ id@id -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call id@result @ -> Pure -//│ deforest > call id@result @ -> Pure +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function id¹#0 @ id² -> Pure +//│ deforest > function id¹#0 @ id³ -> Pure +//│ deforest > function id¹#0 @ id⁴ -> Pure +//│ deforest > call +⁰@result¹ @ -> Pure +//│ deforest > call +⁰@result⁰ @ f2² -> Pure +//│ deforest > call +⁰@result⁰ @ f2¹ -> Pure +//│ deforest > call f1⁰@result⁴ @ -> UnsafeEta +//│ deforest > call f2⁰@result² @ -> UnsafeEta +//│ deforest > call id¹@result³ @ -> Pure +//│ deforest > call id¹@result⁵ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> @@ -1944,25 +1944,25 @@ fun f2(a2) = if a2 is AA(a) then a + 2 fun wrap(a) = a f1(wrap(p(2))) + f2(p(1)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f1#0 @ f1@f1 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function f2#0 @ f2@f2 -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function p#0 @ p@p -> UnsafeEta -//│ deforest > function wrap#0 @ wrap@wrap -> Pure -//│ deforest > function wrap#0 @ wrap@wrap -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f1@f1 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call +@result @ f2@f2 -> Pure -//│ deforest > call f1@result @ -> UnsafeEta -//│ deforest > call f2@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call p@result @ -> UnsafeEta -//│ deforest > call wrap@result @ -> Pure +//│ deforest > function f1⁰#0 @ f1² -> UnsafeEta +//│ deforest > function f1⁰#0 @ f1¹ -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2² -> UnsafeEta +//│ deforest > function f2⁰#0 @ f2¹ -> UnsafeEta +//│ deforest > function p³#0 @ p⁴ -> UnsafeEta +//│ deforest > function p³#0 @ p⁵ -> UnsafeEta +//│ deforest > function p³#0 @ p⁶ -> UnsafeEta +//│ deforest > function wrap⁰#0 @ wrap² -> Pure +//│ deforest > function wrap⁰#0 @ wrap¹ -> Pure +//│ deforest > call +⁰@result² @ -> Pure +//│ deforest > call +⁰@result¹ @ f1² -> Pure +//│ deforest > call +⁰@result¹ @ f1¹ -> Pure +//│ deforest > call +⁰@result⁰ @ f2² -> Pure +//│ deforest > call +⁰@result⁰ @ f2¹ -> Pure +//│ deforest > call f1⁰@result⁵ @ -> UnsafeEta +//│ deforest > call f2⁰@result³ @ -> UnsafeEta +//│ deforest > call p³@result⁴ @ -> UnsafeEta +//│ deforest > call p³@result⁷ @ -> UnsafeEta +//│ deforest > call wrap⁰@result⁶ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(x³⁹) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls b/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls index d78fe9b08e..3c091cace3 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/stratvarNaming.mls @@ -38,25 +38,25 @@ f(3) //│ deforest > tmp_for_f⁰ //│ deforest > <<< non-affine syms <<< //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ g@g -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ f@f -> UnsafeEta -//│ deforest > function g#0 @ g@g -> UnsafeEta -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ f@f -> Pure -//│ deforest > call -@result @ g@g -> Pure -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ f@f -> UnsafeEta -//│ deforest > call equals@result @ g@g -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ f@f -> UnsafeEta -//│ deforest > call f@result @ g@g -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ f@f -> UnsafeEta -//│ deforest > call g@result @ g@g -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function f⁰#0 @ g⁰ -> UnsafeEta +//│ deforest > function g¹#0 @ f² -> UnsafeEta +//│ deforest > function g¹#0 @ f¹ -> UnsafeEta +//│ deforest > function g¹#0 @ g⁰ -> UnsafeEta +//│ deforest > call -⁰@result¹ @ f² -> Pure +//│ deforest > call -⁰@result¹ @ f¹ -> Pure +//│ deforest > call -⁰@result¹ @ g⁰ -> Pure +//│ deforest > call equals@result⁰ @ f² -> UnsafeEta +//│ deforest > call equals@result⁰ @ f¹ -> UnsafeEta +//│ deforest > call equals@result⁰ @ g⁰ -> UnsafeEta +//│ deforest > call f⁰@result³ @ f² -> UnsafeEta +//│ deforest > call f⁰@result³ @ f¹ -> UnsafeEta +//│ deforest > call f⁰@result³ @ g⁰ -> UnsafeEta +//│ deforest > call f⁰@result⁴ @ -> UnsafeEta +//│ deforest > call g¹@result² @ f² -> UnsafeEta +//│ deforest > call g¹@result² @ f¹ -> UnsafeEta +//│ deforest > call g¹@result² @ g⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< diff --git a/hkmc2/shared/src/test/mlscript/deforest/todos.mls b/hkmc2/shared/src/test/mlscript/deforest/todos.mls index b85fe4b1a1..d20f7e51bf 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/todos.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/todos.mls @@ -45,35 +45,35 @@ fun f(a) = if a is let p = AA(AA(AA(10))) test(p) + f(p) + test(AA(AA(AA(10)))) + test(B) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call -@result @ test@test -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function f⁰#0 @ f² -> UnsafeEta +//│ deforest > function f⁰#0 @ f¹ -> UnsafeEta +//│ deforest > function test⁰#0 @ test² -> UnsafeEta +//│ deforest > function test⁰#0 @ test³ -> UnsafeEta +//│ deforest > function test⁰#0 @ test¹ -> UnsafeEta +//│ deforest > function test⁰#0 @ test⁴ -> UnsafeEta +//│ deforest > call +⁰@result² @ test² -> Pure +//│ deforest > call +⁰@result² @ test³ -> Pure +//│ deforest > call +⁰@result² @ test¹ -> Pure +//│ deforest > call +⁰@result² @ test⁴ -> Pure +//│ deforest > call +⁰@result⁰ @ test² -> Pure +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test¹ -> Pure +//│ deforest > call +⁰@result⁰ @ test⁴ -> Pure +//│ deforest > call +⁰@result⁴ @ -> Pure +//│ deforest > call +⁰@result⁶ @ -> Pure +//│ deforest > call +⁰@result⁸ @ -> Pure +//│ deforest > call -⁰@result³ @ test² -> Pure +//│ deforest > call -⁰@result³ @ test³ -> Pure +//│ deforest > call -⁰@result³ @ test¹ -> Pure +//│ deforest > call -⁰@result³ @ test⁴ -> Pure +//│ deforest > call -⁰@result¹ @ test² -> Pure +//│ deforest > call -⁰@result¹ @ test³ -> Pure +//│ deforest > call -⁰@result¹ @ test¹ -> Pure +//│ deforest > call -⁰@result¹ @ test⁴ -> Pure +//│ deforest > call f⁰@result⁹ @ -> UnsafeEta +//│ deforest > call test⁰@result¹⁰ @ -> UnsafeEta +//│ deforest > call test⁰@result⁵ @ -> UnsafeEta +//│ deforest > call test⁰@result⁷ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > B⁰ -> @@ -224,11 +224,11 @@ fun test() = Global(x) then Local(x + 1) test() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > function test#0 @ test@test -> UnsafeEta -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call test@result @ -> UnsafeEta +//│ deforest > function test²#0 @ test³ -> UnsafeEta +//│ deforest > function test²#0 @ test⁴ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ test³ -> Pure +//│ deforest > call +⁰@result⁰ @ test⁴ -> Pure +//│ deforest > call test²@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Global⁰(1) -> @@ -257,20 +257,20 @@ fun test() = inner(x) + inner(x) test() //│ deforest > >>> effect-analysis results >>> -//│ deforest > function inner#0 @ inner@inner -> Pure -//│ deforest > function inner#0 @ test@test.inner@inner -> Pure -//│ deforest > function inner#0 @ test@test.inner@inner -> Pure -//│ deforest > function inner#0 @ test@test.inner@inner -> Pure -//│ deforest > function inner#0 @ test@test.inner@inner -> Pure -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > function test#0 @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call +@result @ test@test -> Pure -//│ deforest > call inner@result @ test@test -> Pure -//│ deforest > call inner@result @ test@test -> Pure -//│ deforest > call inner@result @ test@test -> Pure -//│ deforest > call inner@result @ test@test -> Pure -//│ deforest > call test@result @ -> Pure +//│ deforest > function inner⁰#0 @ inner³ -> Pure +//│ deforest > function inner⁰#0 @ test².inner² -> Pure +//│ deforest > function inner⁰#0 @ test².inner¹ -> Pure +//│ deforest > function inner⁰#0 @ test⁴.inner² -> Pure +//│ deforest > function inner⁰#0 @ test⁴.inner¹ -> Pure +//│ deforest > function test³#0 @ test² -> Pure +//│ deforest > function test³#0 @ test⁴ -> Pure +//│ deforest > call +⁰@result² @ test² -> Pure +//│ deforest > call +⁰@result² @ test⁴ -> Pure +//│ deforest > call inner⁰@result¹ @ test² -> Pure +//│ deforest > call inner⁰@result¹ @ test⁴ -> Pure +//│ deforest > call inner⁰@result⁰ @ test² -> Pure +//│ deforest > call inner⁰@result⁰ @ test⁴ -> Pure +//│ deforest > call test³@result³ @ -> Pure //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > <<< fusing <<< @@ -282,12 +282,12 @@ test() fun f(x) = if x is A then 1 f(A) + f(A) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > function f#0 @ f@f -> UnsafeEta -//│ deforest > call +@result @ -> Pure -//│ deforest > call f@result @ -> UnsafeEta -//│ deforest > call f@result @ -> UnsafeEta +//│ deforest > function f²#0 @ f³ -> UnsafeEta +//│ deforest > function f²#0 @ f⁴ -> UnsafeEta +//│ deforest > function f²#0 @ f⁵ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ -> Pure +//│ deforest > call f²@result² @ -> UnsafeEta +//│ deforest > call f²@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > A⁰ -> @@ -306,11 +306,11 @@ module Test with AA(y) then x + y Test.Test2.foo(AA(2)) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > function foo#0 @ foo@foo -> UnsafeEta -//│ deforest > call +@result @ foo@foo -> Pure -//│ deforest > call +@result @ foo@foo -> Pure -//│ deforest > call foo@result @ -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo² -> UnsafeEta +//│ deforest > function foo⁰#0 @ foo¹ -> UnsafeEta +//│ deforest > call +⁰@result⁰ @ foo² -> Pure +//│ deforest > call +⁰@result⁰ @ foo¹ -> Pure +//│ deforest > call foo@result¹ @ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > AA⁰(2) -> diff --git a/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls b/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls index ba5377244b..9a1372d226 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/zipunzip.mls @@ -22,55 +22,55 @@ fun enumFromTo(a, b) = if a < b then a :: enumFromTo(a + 1, b) else Nil fun testUnzipZip(n) = unzip(zip(id(enumFromTo(1, n)), id(enumFromTo(2, n + 3)))) testUnzipZip(3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function enumFromTo#0 @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function enumFromTo#0 @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > function testUnzipZip#0 @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > function testUnzipZip#0 @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > function unzip#0 @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta -//│ deforest > function unzip#0 @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta -//│ deforest > function unzip#0 @ unzip@unzip -> UnsafeEta -//│ deforest > function zip#0 @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ zip@zip -> UnsafeEta -//│ deforest > call +@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ testUnzipZip@testUnzipZip -> Pure -//│ deforest > call +@result @ testUnzipZip@testUnzipZip -> Pure -//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call +@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call <@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> Pure -//│ deforest > call enumFromTo@result @ enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call enumFromTo@result @ testUnzipZip@testUnzipZip.enumFromTo@enumFromTo -> UnsafeEta -//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call id@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call testUnzipZip@result @ -> UnsafeEta -//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta -//│ deforest > call unzip@result @ testUnzipZip@testUnzipZip.unzip@unzip -> UnsafeEta -//│ deforest > call unzip@result @ unzip@unzip -> UnsafeEta -//│ deforest > call zip@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call zip@result @ testUnzipZip@testUnzipZip -> UnsafeEta -//│ deforest > call zip@result @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ testUnzipZip@testUnzipZip.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ enumFromTo³ -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ testUnzipZip².enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ testUnzipZip².enumFromTo¹ -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ testUnzipZip⁰.enumFromTo² -> UnsafeEta +//│ deforest > function enumFromTo⁰#0 @ testUnzipZip⁰.enumFromTo¹ -> UnsafeEta +//│ deforest > function testUnzipZip¹#0 @ testUnzipZip² -> UnsafeEta +//│ deforest > function testUnzipZip¹#0 @ testUnzipZip⁰ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ testUnzipZip².unzip¹ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ testUnzipZip⁰.unzip¹ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ unzip² -> UnsafeEta +//│ deforest > function zip⁰#0 @ testUnzipZip².zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ testUnzipZip⁰.zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ zip² -> UnsafeEta +//│ deforest > call +⁰@result¹ @ enumFromTo³ -> Pure +//│ deforest > call +⁰@result¹ @ testUnzipZip².enumFromTo² -> Pure +//│ deforest > call +⁰@result¹ @ testUnzipZip².enumFromTo¹ -> Pure +//│ deforest > call +⁰@result¹ @ testUnzipZip⁰.enumFromTo² -> Pure +//│ deforest > call +⁰@result¹ @ testUnzipZip⁰.enumFromTo¹ -> Pure +//│ deforest > call +⁰@result⁵ @ testUnzipZip² -> Pure +//│ deforest > call +⁰@result⁵ @ testUnzipZip⁰ -> Pure +//│ deforest > call <⁰@result² @ enumFromTo³ -> Pure +//│ deforest > call <⁰@result² @ testUnzipZip².enumFromTo² -> Pure +//│ deforest > call <⁰@result² @ testUnzipZip².enumFromTo¹ -> Pure +//│ deforest > call <⁰@result² @ testUnzipZip⁰.enumFromTo² -> Pure +//│ deforest > call <⁰@result² @ testUnzipZip⁰.enumFromTo¹ -> Pure +//│ deforest > call enumFromTo⁰@result³ @ testUnzipZip² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result³ @ testUnzipZip⁰ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁰ @ enumFromTo³ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁰ @ testUnzipZip².enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁰ @ testUnzipZip².enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁰ @ testUnzipZip⁰.enumFromTo² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁰ @ testUnzipZip⁰.enumFromTo¹ -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ testUnzipZip² -> UnsafeEta +//│ deforest > call enumFromTo⁰@result⁶ @ testUnzipZip⁰ -> UnsafeEta +//│ deforest > call id@result⁴ @ testUnzipZip² -> UnsafeEta +//│ deforest > call id@result⁴ @ testUnzipZip⁰ -> UnsafeEta +//│ deforest > call id@result⁷ @ testUnzipZip² -> UnsafeEta +//│ deforest > call id@result⁷ @ testUnzipZip⁰ -> UnsafeEta +//│ deforest > call testUnzipZip¹@result¹² @ -> UnsafeEta +//│ deforest > call unzip⁰@result¹¹ @ testUnzipZip² -> UnsafeEta +//│ deforest > call unzip⁰@result¹¹ @ testUnzipZip⁰ -> UnsafeEta +//│ deforest > call unzip⁰@result¹⁰ @ testUnzipZip².unzip¹ -> UnsafeEta +//│ deforest > call unzip⁰@result¹⁰ @ testUnzipZip⁰.unzip¹ -> UnsafeEta +//│ deforest > call unzip⁰@result¹⁰ @ unzip² -> UnsafeEta +//│ deforest > call zip⁰@result⁸ @ testUnzipZip².zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result⁸ @ testUnzipZip⁰.zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result⁸ @ zip² -> UnsafeEta +//│ deforest > call zip⁰@result⁹ @ testUnzipZip² -> UnsafeEta +//│ deforest > call zip⁰@result⁹ @ testUnzipZip⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -114,44 +114,44 @@ fun testZipUnzip(n) = if unzip(id(makeZippedList(n))) is Pair(xs, ys) then zip(xs, ys) testZipUnzip(3) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function makeZippedList#0 @ makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > function makeZippedList#0 @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > function makeZippedList#0 @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > function testZipUnzip#0 @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > function testZipUnzip#0 @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > function unzip#0 @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta -//│ deforest > function unzip#0 @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta -//│ deforest > function unzip#0 @ unzip@unzip -> UnsafeEta -//│ deforest > function zip#0 @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ zip@zip -> UnsafeEta -//│ deforest > call +@result @ makeZippedList@makeZippedList -> Pure -//│ deforest > call +@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call +@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call -@result @ makeZippedList@makeZippedList -> Pure -//│ deforest > call -@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call -@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call >@result @ makeZippedList@makeZippedList -> Pure -//│ deforest > call >@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call >@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call id@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call id@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call makeZippedList@result @ makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipUnzip@testZipUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > call testZipUnzip@result @ -> UnsafeEta -//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta -//│ deforest > call unzip@result @ testZipUnzip@testZipUnzip.unzip@unzip -> UnsafeEta -//│ deforest > call unzip@result @ unzip@unzip -> UnsafeEta -//│ deforest > call zip@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call zip@result @ testZipUnzip@testZipUnzip -> UnsafeEta -//│ deforest > call zip@result @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ testZipUnzip@testZipUnzip.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > function makeZippedList⁰#0 @ makeZippedList² -> UnsafeEta +//│ deforest > function makeZippedList⁰#0 @ testZipUnzip².makeZippedList¹ -> UnsafeEta +//│ deforest > function makeZippedList⁰#0 @ testZipUnzip⁰.makeZippedList¹ -> UnsafeEta +//│ deforest > function testZipUnzip¹#0 @ testZipUnzip² -> UnsafeEta +//│ deforest > function testZipUnzip¹#0 @ testZipUnzip⁰ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ testZipUnzip².unzip¹ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ testZipUnzip⁰.unzip¹ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ unzip² -> UnsafeEta +//│ deforest > function zip⁰#0 @ testZipUnzip².zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ testZipUnzip⁰.zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ zip² -> UnsafeEta +//│ deforest > call +⁰@result² @ makeZippedList² -> Pure +//│ deforest > call +⁰@result² @ testZipUnzip².makeZippedList¹ -> Pure +//│ deforest > call +⁰@result² @ testZipUnzip⁰.makeZippedList¹ -> Pure +//│ deforest > call -⁰@result¹ @ makeZippedList² -> Pure +//│ deforest > call -⁰@result¹ @ testZipUnzip².makeZippedList¹ -> Pure +//│ deforest > call -⁰@result¹ @ testZipUnzip⁰.makeZippedList¹ -> Pure +//│ deforest > call >⁰@result³ @ makeZippedList² -> Pure +//│ deforest > call >⁰@result³ @ testZipUnzip².makeZippedList¹ -> Pure +//│ deforest > call >⁰@result³ @ testZipUnzip⁰.makeZippedList¹ -> Pure +//│ deforest > call id@result⁵ @ testZipUnzip² -> UnsafeEta +//│ deforest > call id@result⁵ @ testZipUnzip⁰ -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁰ @ makeZippedList² -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁰ @ testZipUnzip².makeZippedList¹ -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁰ @ testZipUnzip⁰.makeZippedList¹ -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁴ @ testZipUnzip² -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁴ @ testZipUnzip⁰ -> UnsafeEta +//│ deforest > call testZipUnzip¹@result¹⁰ @ -> UnsafeEta +//│ deforest > call unzip⁰@result⁶ @ testZipUnzip².unzip¹ -> UnsafeEta +//│ deforest > call unzip⁰@result⁶ @ testZipUnzip⁰.unzip¹ -> UnsafeEta +//│ deforest > call unzip⁰@result⁶ @ unzip² -> UnsafeEta +//│ deforest > call unzip⁰@result⁷ @ testZipUnzip² -> UnsafeEta +//│ deforest > call unzip⁰@result⁷ @ testZipUnzip⁰ -> UnsafeEta +//│ deforest > call zip⁰@result⁸ @ testZipUnzip².zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result⁸ @ testZipUnzip⁰.zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result⁸ @ zip² -> UnsafeEta +//│ deforest > call zip⁰@result⁹ @ testZipUnzip² -> UnsafeEta +//│ deforest > call zip⁰@result⁹ @ testZipUnzip⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> @@ -200,71 +200,71 @@ fun testZipMapBothUnzip(n) = if unzip(id(makeZippedList(n))) is ) testZipMapBothUnzip(4) //│ deforest > >>> effect-analysis results >>> -//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > function lambda#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > function makeZippedList#0 @ makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > function makeZippedList#0 @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > function makeZippedList#0 @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > function map#0 @ map@map -> UnsafeEta -//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > function map#0 @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > function testZipMapBothUnzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > function testZipMapBothUnzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > function unzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta -//│ deforest > function unzip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta -//│ deforest > function unzip#0 @ unzip@unzip -> UnsafeEta -//│ deforest > function zip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta -//│ deforest > function zip#0 @ zip@zip -> UnsafeEta -//│ deforest > call *@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > call *@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > call +@result @ makeZippedList@makeZippedList -> Pure -//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip -> Pure -//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call +@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call -@result @ makeZippedList@makeZippedList -> Pure -//│ deforest > call -@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call -@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call >@result @ makeZippedList@makeZippedList -> Pure -//│ deforest > call >@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call >@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> Pure -//│ deforest > call f@result @ map@map -> UnsafeEta -//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure -//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure -//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure -//│ deforest > call f@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> Pure -//│ deforest > call id@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call id@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call makeZippedList@result @ makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > call makeZippedList@result @ testZipMapBothUnzip@testZipMapBothUnzip.makeZippedList@makeZippedList -> UnsafeEta -//│ deforest > call map@result @ map@map -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > call map@result @ testZipMapBothUnzip@testZipMapBothUnzip.map@map -> UnsafeEta -//│ deforest > call testZipMapBothUnzip@result @ -> UnsafeEta -//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta -//│ deforest > call unzip@result @ testZipMapBothUnzip@testZipMapBothUnzip.unzip@unzip -> UnsafeEta -//│ deforest > call unzip@result @ unzip@unzip -> UnsafeEta -//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip -> UnsafeEta -//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ testZipMapBothUnzip@testZipMapBothUnzip.zip@zip -> UnsafeEta -//│ deforest > call zip@result @ zip@zip -> UnsafeEta +//│ deforest > function lambda¹#0 @ testZipMapBothUnzip² -> Pure +//│ deforest > function lambda¹#0 @ testZipMapBothUnzip⁰ -> Pure +//│ deforest > function lambda⁰#0 @ testZipMapBothUnzip² -> Pure +//│ deforest > function lambda⁰#0 @ testZipMapBothUnzip⁰ -> Pure +//│ deforest > function makeZippedList⁰#0 @ makeZippedList² -> UnsafeEta +//│ deforest > function makeZippedList⁰#0 @ testZipMapBothUnzip².makeZippedList¹ -> UnsafeEta +//│ deforest > function makeZippedList⁰#0 @ testZipMapBothUnzip⁰.makeZippedList¹ -> UnsafeEta +//│ deforest > function map⁰#0 @ map³ -> UnsafeEta +//│ deforest > function map⁰#0 @ testZipMapBothUnzip².map² -> UnsafeEta +//│ deforest > function map⁰#0 @ testZipMapBothUnzip².map¹ -> UnsafeEta +//│ deforest > function map⁰#0 @ testZipMapBothUnzip⁰.map² -> UnsafeEta +//│ deforest > function map⁰#0 @ testZipMapBothUnzip⁰.map¹ -> UnsafeEta +//│ deforest > function testZipMapBothUnzip¹#0 @ testZipMapBothUnzip² -> UnsafeEta +//│ deforest > function testZipMapBothUnzip¹#0 @ testZipMapBothUnzip⁰ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ testZipMapBothUnzip².unzip¹ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ testZipMapBothUnzip⁰.unzip¹ -> UnsafeEta +//│ deforest > function unzip⁰#0 @ unzip² -> UnsafeEta +//│ deforest > function zip⁰#0 @ testZipMapBothUnzip².zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ testZipMapBothUnzip⁰.zip¹ -> UnsafeEta +//│ deforest > function zip⁰#0 @ zip² -> UnsafeEta +//│ deforest > call *⁰@result¹² @ testZipMapBothUnzip² -> Pure +//│ deforest > call *⁰@result¹² @ testZipMapBothUnzip⁰ -> Pure +//│ deforest > call +⁰@result² @ makeZippedList² -> Pure +//│ deforest > call +⁰@result² @ testZipMapBothUnzip².makeZippedList¹ -> Pure +//│ deforest > call +⁰@result² @ testZipMapBothUnzip⁰.makeZippedList¹ -> Pure +//│ deforest > call +⁰@result⁸ @ testZipMapBothUnzip² -> Pure +//│ deforest > call +⁰@result⁸ @ testZipMapBothUnzip⁰ -> Pure +//│ deforest > call -⁰@result¹ @ makeZippedList² -> Pure +//│ deforest > call -⁰@result¹ @ testZipMapBothUnzip².makeZippedList¹ -> Pure +//│ deforest > call -⁰@result¹ @ testZipMapBothUnzip⁰.makeZippedList¹ -> Pure +//│ deforest > call >⁰@result³ @ makeZippedList² -> Pure +//│ deforest > call >⁰@result³ @ testZipMapBothUnzip².makeZippedList¹ -> Pure +//│ deforest > call >⁰@result³ @ testZipMapBothUnzip⁰.makeZippedList¹ -> Pure +//│ deforest > call f⁰@result¹⁰ @ map³ -> UnsafeEta +//│ deforest > call f⁰@result¹⁰ @ testZipMapBothUnzip².map² -> Pure +//│ deforest > call f⁰@result¹⁰ @ testZipMapBothUnzip².map¹ -> Pure +//│ deforest > call f⁰@result¹⁰ @ testZipMapBothUnzip⁰.map² -> Pure +//│ deforest > call f⁰@result¹⁰ @ testZipMapBothUnzip⁰.map¹ -> Pure +//│ deforest > call id@result⁵ @ testZipMapBothUnzip² -> UnsafeEta +//│ deforest > call id@result⁵ @ testZipMapBothUnzip⁰ -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁰ @ makeZippedList² -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁰ @ testZipMapBothUnzip².makeZippedList¹ -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁰ @ testZipMapBothUnzip⁰.makeZippedList¹ -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁴ @ testZipMapBothUnzip² -> UnsafeEta +//│ deforest > call makeZippedList⁰@result⁴ @ testZipMapBothUnzip⁰ -> UnsafeEta +//│ deforest > call map⁰@result¹³ @ testZipMapBothUnzip² -> UnsafeEta +//│ deforest > call map⁰@result¹³ @ testZipMapBothUnzip⁰ -> UnsafeEta +//│ deforest > call map⁰@result¹¹ @ testZipMapBothUnzip² -> UnsafeEta +//│ deforest > call map⁰@result¹¹ @ testZipMapBothUnzip⁰ -> UnsafeEta +//│ deforest > call map⁰@result⁹ @ map³ -> UnsafeEta +//│ deforest > call map⁰@result⁹ @ testZipMapBothUnzip².map² -> UnsafeEta +//│ deforest > call map⁰@result⁹ @ testZipMapBothUnzip².map¹ -> UnsafeEta +//│ deforest > call map⁰@result⁹ @ testZipMapBothUnzip⁰.map² -> UnsafeEta +//│ deforest > call map⁰@result⁹ @ testZipMapBothUnzip⁰.map¹ -> UnsafeEta +//│ deforest > call testZipMapBothUnzip¹@result¹⁶ @ -> UnsafeEta +//│ deforest > call unzip⁰@result⁶ @ testZipMapBothUnzip².unzip¹ -> UnsafeEta +//│ deforest > call unzip⁰@result⁶ @ testZipMapBothUnzip⁰.unzip¹ -> UnsafeEta +//│ deforest > call unzip⁰@result⁶ @ unzip² -> UnsafeEta +//│ deforest > call unzip⁰@result⁷ @ testZipMapBothUnzip² -> UnsafeEta +//│ deforest > call unzip⁰@result⁷ @ testZipMapBothUnzip⁰ -> UnsafeEta +//│ deforest > call zip⁰@result¹⁴ @ testZipMapBothUnzip².zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result¹⁴ @ testZipMapBothUnzip⁰.zip¹ -> UnsafeEta +//│ deforest > call zip⁰@result¹⁴ @ zip² -> UnsafeEta +//│ deforest > call zip⁰@result¹⁵ @ testZipMapBothUnzip² -> UnsafeEta +//│ deforest > call zip⁰@result¹⁵ @ testZipMapBothUnzip⁰ -> UnsafeEta //│ deforest > <<< effect-analysis results <<< //│ deforest > >>> fusing >>> //│ deforest > Nil⁰ -> diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls index 64dda93872..f2d49e1ef1 100644 --- a/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Basic.mls @@ -15,10 +15,10 @@ declare fun unsafe(): Anything fun leaf_pure(x) = x + 42 fun node_pure(x) = leaf_pure(x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_pure#0 @ -> Pure -//│ flow-analysis > function node_pure#0 @ -> Pure -//│ flow-analysis > call +@result @ -> Pure -//│ flow-analysis > call leaf_pure@result @ -> Pure +//│ flow-analysis > function leaf_pure⁰#0 @ -> Pure +//│ flow-analysis > function node_pure⁰#0 @ -> Pure +//│ flow-analysis > call +⁰@result¹ @ -> Pure +//│ flow-analysis > call leaf_pure⁰@result⁰ @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< @@ -26,10 +26,10 @@ fun node_pure(x) = leaf_pure(x) fun leaf_unsafe(x) = unsafe() fun node_unsafe(x) = leaf_unsafe(x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_unsafe#0 @ -> UnsafeEta -//│ flow-analysis > function node_unsafe#0 @ -> UnsafeEta -//│ flow-analysis > call leaf_unsafe@result @ -> UnsafeEta -//│ flow-analysis > call unsafe@result @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe⁰#0 @ -> UnsafeEta +//│ flow-analysis > function node_unsafe⁰#0 @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe⁰@result⁰ @ -> UnsafeEta +//│ flow-analysis > call unsafe@result¹ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -37,10 +37,10 @@ fun node_unsafe(x) = leaf_unsafe(x) fun leaf_unsafe(x) = print(42) fun node_unsafe(x) = leaf_unsafe(x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_unsafe#0 @ -> UnsafeEta -//│ flow-analysis > function node_unsafe#0 @ -> UnsafeEta -//│ flow-analysis > call leaf_unsafe@result @ -> UnsafeEta -//│ flow-analysis > call print@result @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe⁰#0 @ -> UnsafeEta +//│ flow-analysis > function node_unsafe⁰#0 @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe⁰@result⁰ @ -> UnsafeEta +//│ flow-analysis > call print@result¹ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -56,31 +56,31 @@ fun node() = leaf_unsafe_public(unsafe) leaf_unsafe_private(unsafe) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function answer#0 @ -> Pure -//│ flow-analysis > function leaf_pure_private#0 @ -> Pure -//│ flow-analysis > function leaf_pure_public#0 @ -> UnsafeEta -//│ flow-analysis > function leaf_unsafe_private#0 @ -> UnsafeEta -//│ flow-analysis > function leaf_unsafe_public#0 @ -> UnsafeEta -//│ flow-analysis > function node#0 @ -> UnsafeEta -//│ flow-analysis > call leaf_pure_private@result @ -> Pure -//│ flow-analysis > call leaf_pure_public@result @ -> UnsafeEta -//│ flow-analysis > call leaf_unsafe_private@result @ -> UnsafeEta -//│ flow-analysis > call leaf_unsafe_public@result @ -> UnsafeEta -//│ flow-analysis > call x@result @ -> Pure -//│ flow-analysis > call x@result @ -> UnsafeEta -//│ flow-analysis > call x@result @ -> UnsafeEta -//│ flow-analysis > call x@result @ -> UnsafeEta +//│ flow-analysis > function answer⁰#0 @ -> Pure +//│ flow-analysis > function leaf_pure_private⁰#0 @ -> Pure +//│ flow-analysis > function leaf_pure_public⁰#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_private⁰#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_public⁰#0 @ -> UnsafeEta +//│ flow-analysis > function node⁰#0 @ -> UnsafeEta +//│ flow-analysis > call leaf_pure_private⁰@result² @ -> Pure +//│ flow-analysis > call leaf_pure_public⁰@result³ @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe_private⁰@result⁰ @ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe_public⁰@result¹ @ -> UnsafeEta +//│ flow-analysis > call x²@result⁶ @ -> Pure +//│ flow-analysis > call x³@result⁷ @ -> UnsafeEta +//│ flow-analysis > call x¹@result⁵ @ -> UnsafeEta +//│ flow-analysis > call x⁰@result⁴ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< // * Recursive calls propagate pure and unsafe. fun node_recursive_pure() = node_recursive_pure() fun node_recursive_unsafe() = unsafe(); node_recursive_unsafe() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function node_recursive_pure#0 @ -> Pure -//│ flow-analysis > function node_recursive_unsafe#0 @ -> UnsafeEta -//│ flow-analysis > call ,@result @ -> Pure -//│ flow-analysis > call node_recursive_unsafe@result @ -> UnsafeEta -//│ flow-analysis > call unsafe@result @ -> UnsafeEta +//│ flow-analysis > function node_recursive_pure⁰#0 @ -> Pure +//│ flow-analysis > function node_recursive_unsafe⁰#0 @ -> UnsafeEta +//│ flow-analysis > call ,⁰@result⁰ @ -> Pure +//│ flow-analysis > call node_recursive_unsafe⁰@result¹ @ -> UnsafeEta +//│ flow-analysis > call unsafe@result² @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -88,10 +88,10 @@ fun node_recursive_unsafe() = unsafe(); node_recursive_unsafe() @pure fun leaf_pure() = unsafe() fun node_pure() = leaf_pure() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_pure#0 @ -> Pure -//│ flow-analysis > function node_pure#0 @ -> Pure -//│ flow-analysis > call leaf_pure@result @ -> Pure -//│ flow-analysis > call unsafe@result @ -> UnsafeEta +//│ flow-analysis > function leaf_pure⁰#0 @ -> Pure +//│ flow-analysis > function node_pure⁰#0 @ -> Pure +//│ flow-analysis > call leaf_pure⁰@result⁰ @ -> Pure +//│ flow-analysis > call unsafe@result¹ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -99,8 +99,8 @@ fun node_pure() = leaf_pure() @pure declare fun leaf_pure(): Anything fun node_pure() = leaf_pure() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function node_pure#0 @ -> Pure -//│ flow-analysis > call leaf_pure@result @ -> Pure +//│ flow-analysis > function node_pure⁰#0 @ -> Pure +//│ flow-analysis > call leaf_pure@result⁰ @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< @@ -116,13 +116,13 @@ fun box_instantiation() = new Box() fun box_pure(box: Box) = box.pure() fun box_unsafe(box: Box) = box.unsafe() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function box_constructor#0 @ -> UnsafeEta -//│ flow-analysis > function box_instantiation#0 @ -> UnsafeEta -//│ flow-analysis > function box_pure#0 @ -> UnsafeEta -//│ flow-analysis > function box_unsafe#0 @ -> UnsafeEta -//│ flow-analysis > call pure@result @ -> UnsafeEta -//│ flow-analysis > call unsafe@result @ -> UnsafeEta -//│ flow-analysis > call unsafe@result @ -> UnsafeEta +//│ flow-analysis > function box_constructor⁰#0 @ -> UnsafeEta +//│ flow-analysis > function box_instantiation⁰#0 @ -> UnsafeEta +//│ flow-analysis > function box_pure⁰#0 @ -> UnsafeEta +//│ flow-analysis > function box_unsafe⁰#0 @ -> UnsafeEta +//│ flow-analysis > call pure@result² @ -> UnsafeEta +//│ flow-analysis > call unsafe@result¹ @ -> UnsafeEta +//│ flow-analysis > call unsafe@result⁰ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -135,30 +135,30 @@ fun node_pure_2(xs) = leaf_pure_2(...xs) fun node_pure_3(xs) = leaf_pure_1(1, 2, 3) fun node_pure_4(xs) = leaf_pure_2(1, 2, 3) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_pure_1#0 @ -> Pure -//│ flow-analysis > function leaf_pure_2#0 @ -> Pure -//│ flow-analysis > function node_pure_1#0 @ -> UnsafeEta -//│ flow-analysis > function node_pure_2#0 @ -> UnsafeEta -//│ flow-analysis > function node_pure_3#0 @ -> Pure -//│ flow-analysis > function node_pure_4#0 @ -> Pure -//│ flow-analysis > call leaf_pure_1@result @ -> Pure -//│ flow-analysis > call leaf_pure_2@result @ -> Pure -//│ flow-analysis > call unsafe@result @ -> UnsafeEta +//│ flow-analysis > function leaf_pure_1⁰#0 @ -> Pure +//│ flow-analysis > function leaf_pure_2⁰#0 @ -> Pure +//│ flow-analysis > function node_pure_1⁰#0 @ -> UnsafeEta +//│ flow-analysis > function node_pure_2⁰#0 @ -> UnsafeEta +//│ flow-analysis > function node_pure_3⁰#0 @ -> Pure +//│ flow-analysis > function node_pure_4⁰#0 @ -> Pure +//│ flow-analysis > call leaf_pure_1⁰@result¹ @ -> Pure +//│ flow-analysis > call leaf_pure_2⁰@result⁰ @ -> Pure +//│ flow-analysis > call unsafe@result² @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< // ? See below... fun pure() = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function pure#0 @ -> Pure +//│ flow-analysis > function pure⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< // ? It seems that flow analysis runs per-block separately... // ? Is that intended? pure() is seen as a unknwon function in leaf_pure. fun leaf_pure(x) = pure() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_pure#0 @ -> UnsafeEta -//│ flow-analysis > call pure@result @ -> UnsafeEta +//│ flow-analysis > function leaf_pure⁰#0 @ -> UnsafeEta +//│ flow-analysis > call pure⁰@result⁰ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -180,28 +180,28 @@ fun node() = leaf_unsafe_public(unsafe) leaf_unsafe_private(unsafe) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function answer#0 @ answer@answer -> Pure -//│ flow-analysis > function answer#0 @ node@node.answer@answer -> Pure -//│ flow-analysis > function answer#0 @ node@node.answer@answer -> Pure -//│ flow-analysis > function leaf_pure_private#0 @ leaf_pure_private@leaf_pure_private -> UnsafeEta -//│ flow-analysis > function leaf_pure_private#0 @ node@node.leaf_pure_private@leaf_pure_private -> Pure -//│ flow-analysis > function leaf_pure_public#0 @ leaf_pure_public@leaf_pure_public -> UnsafeEta -//│ flow-analysis > function leaf_pure_public#0 @ node@node.leaf_pure_public@leaf_pure_public -> Pure -//│ flow-analysis > function leaf_unsafe_private#0 @ leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta -//│ flow-analysis > function leaf_unsafe_private#0 @ node@node.leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta -//│ flow-analysis > function leaf_unsafe_public#0 @ leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta -//│ flow-analysis > function leaf_unsafe_public#0 @ node@node.leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta -//│ flow-analysis > function node#0 @ node@node -> UnsafeEta -//│ flow-analysis > call leaf_pure_private@result @ node@node -> Pure -//│ flow-analysis > call leaf_pure_public@result @ node@node -> Pure -//│ flow-analysis > call leaf_unsafe_private@result @ node@node -> UnsafeEta -//│ flow-analysis > call leaf_unsafe_public@result @ node@node -> UnsafeEta -//│ flow-analysis > call x@result @ leaf_pure_private@leaf_pure_private -> UnsafeEta -//│ flow-analysis > call x@result @ leaf_pure_public@leaf_pure_public -> UnsafeEta -//│ flow-analysis > call x@result @ leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta -//│ flow-analysis > call x@result @ leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta -//│ flow-analysis > call x@result @ node@node.leaf_pure_private@leaf_pure_private -> Pure -//│ flow-analysis > call x@result @ node@node.leaf_pure_public@leaf_pure_public -> Pure -//│ flow-analysis > call x@result @ node@node.leaf_unsafe_private@leaf_unsafe_private -> UnsafeEta -//│ flow-analysis > call x@result @ node@node.leaf_unsafe_public@leaf_unsafe_public -> UnsafeEta +//│ flow-analysis > function answer⁰#0 @ answer³ -> Pure +//│ flow-analysis > function answer⁰#0 @ node⁰.answer² -> Pure +//│ flow-analysis > function answer⁰#0 @ node⁰.answer¹ -> Pure +//│ flow-analysis > function leaf_pure_private⁰#0 @ leaf_pure_private² -> UnsafeEta +//│ flow-analysis > function leaf_pure_private⁰#0 @ node⁰.leaf_pure_private¹ -> Pure +//│ flow-analysis > function leaf_pure_public⁰#0 @ leaf_pure_public² -> UnsafeEta +//│ flow-analysis > function leaf_pure_public⁰#0 @ node⁰.leaf_pure_public¹ -> Pure +//│ flow-analysis > function leaf_unsafe_private⁰#0 @ leaf_unsafe_private² -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_private⁰#0 @ node⁰.leaf_unsafe_private¹ -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_public⁰#0 @ leaf_unsafe_public² -> UnsafeEta +//│ flow-analysis > function leaf_unsafe_public⁰#0 @ node⁰.leaf_unsafe_public¹ -> UnsafeEta +//│ flow-analysis > function node¹#0 @ node⁰ -> UnsafeEta +//│ flow-analysis > call leaf_pure_private⁰@result³ @ node⁰ -> Pure +//│ flow-analysis > call leaf_pure_public⁰@result¹ @ node⁰ -> Pure +//│ flow-analysis > call leaf_unsafe_private⁰@result⁷ @ node⁰ -> UnsafeEta +//│ flow-analysis > call leaf_unsafe_public⁰@result⁵ @ node⁰ -> UnsafeEta +//│ flow-analysis > call x²@result⁴ @ leaf_unsafe_public² -> UnsafeEta +//│ flow-analysis > call x²@result⁴ @ node⁰.leaf_unsafe_public¹ -> UnsafeEta +//│ flow-analysis > call x³@result⁶ @ leaf_unsafe_private² -> UnsafeEta +//│ flow-analysis > call x³@result⁶ @ node⁰.leaf_unsafe_private¹ -> UnsafeEta +//│ flow-analysis > call x¹@result² @ leaf_pure_private² -> UnsafeEta +//│ flow-analysis > call x¹@result² @ node⁰.leaf_pure_private¹ -> Pure +//│ flow-analysis > call x⁰@result⁰ @ leaf_pure_public² -> UnsafeEta +//│ flow-analysis > call x⁰@result⁰ @ node⁰.leaf_pure_public¹ -> Pure //│ flow-analysis > <<< effect-analysis results <<< diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls index c7bfef00e6..3120297313 100644 --- a/hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Imports.mls @@ -10,12 +10,12 @@ fun leaf(x) = print(x) fun node(x) = leaf(x) fun qualified(x) = Predef.print(x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf#0 @ -> UnsafeEta -//│ flow-analysis > function node#0 @ -> UnsafeEta -//│ flow-analysis > function qualified#0 @ -> UnsafeEta -//│ flow-analysis > call leaf@result @ -> UnsafeEta -//│ flow-analysis > call print@result @ -> UnsafeEta -//│ flow-analysis > call print@result @ -> UnsafeEta +//│ flow-analysis > function leaf⁰#0 @ -> UnsafeEta +//│ flow-analysis > function node⁰#0 @ -> UnsafeEta +//│ flow-analysis > function qualified⁰#0 @ -> UnsafeEta +//│ flow-analysis > call leaf⁰@result¹ @ -> UnsafeEta +//│ flow-analysis > call print@result² @ -> UnsafeEta +//│ flow-analysis > call print@result⁰ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -24,13 +24,13 @@ private fun invoke(f, x) = f(x) fun indirect(x) = invoke(print, x) fun pure_callback(x) = invoke(y => y, x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function indirect#0 @ -> UnsafeEta -//│ flow-analysis > function invoke#0 @ -> UnsafeEta -//│ flow-analysis > function lambda#0 @ -> Pure -//│ flow-analysis > function pure_callback#0 @ -> UnsafeEta -//│ flow-analysis > call f@result @ -> UnsafeEta -//│ flow-analysis > call invoke@result @ -> UnsafeEta -//│ flow-analysis > call invoke@result @ -> UnsafeEta +//│ flow-analysis > function indirect⁰#0 @ -> UnsafeEta +//│ flow-analysis > function invoke⁰#0 @ -> UnsafeEta +//│ flow-analysis > function lambda⁰#0 @ -> Pure +//│ flow-analysis > function pure_callback⁰#0 @ -> UnsafeEta +//│ flow-analysis > call f⁰@result² @ -> UnsafeEta +//│ flow-analysis > call invoke⁰@result¹ @ -> UnsafeEta +//│ flow-analysis > call invoke⁰@result⁰ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -43,14 +43,14 @@ fun leaf(x) = print(x) fun node(x) = leaf(x) fun qualified(x) = Predef.print(x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf#0 @ leaf@leaf -> UnsafeEta -//│ flow-analysis > function leaf#0 @ node@node.leaf@leaf -> UnsafeEta -//│ flow-analysis > function node#0 @ node@node -> UnsafeEta -//│ flow-analysis > function qualified#0 @ qualified@qualified -> UnsafeEta -//│ flow-analysis > call leaf@result @ node@node -> UnsafeEta -//│ flow-analysis > call print@result @ leaf@leaf -> UnsafeEta -//│ flow-analysis > call print@result @ node@node.leaf@leaf -> UnsafeEta -//│ flow-analysis > call print@result @ qualified@qualified -> UnsafeEta +//│ flow-analysis > function leaf⁰#0 @ leaf² -> UnsafeEta +//│ flow-analysis > function leaf⁰#0 @ node⁰.leaf¹ -> UnsafeEta +//│ flow-analysis > function node¹#0 @ node⁰ -> UnsafeEta +//│ flow-analysis > function qualified⁰#0 @ qualified¹ -> UnsafeEta +//│ flow-analysis > call leaf⁰@result² @ node⁰ -> UnsafeEta +//│ flow-analysis > call print@result¹ @ leaf² -> UnsafeEta +//│ flow-analysis > call print@result¹ @ node⁰.leaf¹ -> UnsafeEta +//│ flow-analysis > call print@result⁰ @ qualified¹ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -59,16 +59,16 @@ private fun invoke(f, x) = f(x) fun indirect(x) = invoke(print, x) fun pure_callback(x) = invoke(y => y, x) //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function indirect#0 @ indirect@indirect -> UnsafeEta -//│ flow-analysis > function invoke#0 @ indirect@indirect.invoke@invoke -> UnsafeEta -//│ flow-analysis > function invoke#0 @ invoke@invoke -> UnsafeEta -//│ flow-analysis > function invoke#0 @ pure_callback@pure_callback.invoke@invoke -> Pure -//│ flow-analysis > function lambda#0 @ lambda@lambda -> Pure -//│ flow-analysis > function lambda#0 @ pure_callback@pure_callback.lambda@lambda -> Pure -//│ flow-analysis > function pure_callback#0 @ pure_callback@pure_callback -> Pure -//│ flow-analysis > call f@result @ indirect@indirect.invoke@invoke -> UnsafeEta -//│ flow-analysis > call f@result @ invoke@invoke -> UnsafeEta -//│ flow-analysis > call f@result @ pure_callback@pure_callback.invoke@invoke -> Pure -//│ flow-analysis > call invoke@result @ indirect@indirect -> UnsafeEta -//│ flow-analysis > call invoke@result @ pure_callback@pure_callback -> Pure +//│ flow-analysis > function indirect¹#0 @ indirect⁰ -> UnsafeEta +//│ flow-analysis > function invoke⁰#0 @ indirect⁰.invoke² -> UnsafeEta +//│ flow-analysis > function invoke⁰#0 @ invoke³ -> UnsafeEta +//│ flow-analysis > function invoke⁰#0 @ pure_callback⁰.invoke¹ -> Pure +//│ flow-analysis > function lambda⁰#0 @ lambda² -> Pure +//│ flow-analysis > function lambda⁰#0 @ pure_callback⁰.lambda¹ -> Pure +//│ flow-analysis > function pure_callback¹#0 @ pure_callback⁰ -> Pure +//│ flow-analysis > call f⁰@result⁰ @ indirect⁰.invoke² -> UnsafeEta +//│ flow-analysis > call f⁰@result⁰ @ invoke³ -> UnsafeEta +//│ flow-analysis > call f⁰@result⁰ @ pure_callback⁰.invoke¹ -> Pure +//│ flow-analysis > call invoke⁰@result² @ indirect⁰ -> UnsafeEta +//│ flow-analysis > call invoke⁰@result¹ @ pure_callback⁰ -> Pure //│ flow-analysis > <<< effect-analysis results <<< diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls index 2613e19684..ad01e02ad7 100644 --- a/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls @@ -11,7 +11,7 @@ let state = 0 fun mutate() = set state = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate#0 @ -> UnsafeEta +//│ flow-analysis > function mutate⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = 0 @@ -21,7 +21,7 @@ fun mutate_local() = let local = 0 set local = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_local#0 @ -> Pure +//│ flow-analysis > function mutate_local⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< @@ -30,7 +30,7 @@ fun mutate_alias(value) = let local = value set local = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_alias#0 @ -> Pure +//│ flow-analysis > function mutate_alias⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< @@ -40,12 +40,12 @@ fun mutate_captured() = () => set local = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function lambda#0 @ -> UnsafeEta -//│ flow-analysis > function lambda$#0 @ -> Pure -//│ flow-analysis > function lambda$#1 @ -> UnsafeEta -//│ flow-analysis > function mutate_captured#0 @ -> UnsafeEta -//│ flow-analysis > call lambda$@result @ -> Pure -//│ flow-analysis > call lambda@result @ -> UnsafeEta +//│ flow-analysis > function lambda$⁰#0 @ -> Pure +//│ flow-analysis > function lambda$⁰#1 @ -> UnsafeEta +//│ flow-analysis > function lambda⁰#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_captured⁰#0 @ -> UnsafeEta +//│ flow-analysis > call lambda$⁰@result⁰ @ -> Pure +//│ flow-analysis > call lambda⁰@result¹ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -54,7 +54,7 @@ let state = mut { value: 0 } fun mutate_field() = set state.value = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_field#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_field⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = {value: 0} @@ -63,7 +63,7 @@ let state = mut [0] fun mutate_element() = set state.[0] = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_element#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_element⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = [0] @@ -78,8 +78,8 @@ fun mutate_local_element() = let local = mut [0] set local.[0] = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_local_element#0 @ -> UnsafeEta -//│ flow-analysis > function mutate_local_field#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_local_element⁰#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_local_field⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -91,8 +91,8 @@ fun mutate_alias_element(xs) = let local = xs set local.[0] = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_alias_element#0 @ -> UnsafeEta -//│ flow-analysis > function mutate_alias_field#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_alias_element⁰#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_alias_field⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -103,7 +103,7 @@ let state = 0 fun observe() = state //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe#0 @ -> UnsafeEta +//│ flow-analysis > function observe⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = 0 @@ -113,7 +113,7 @@ fun observe_local() = let local = 0 local //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe_local#0 @ -> Pure +//│ flow-analysis > function observe_local⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< @@ -122,7 +122,7 @@ fun observe_alias(value) = let local = value local //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe_alias#0 @ -> Pure +//│ flow-analysis > function observe_alias⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< @@ -132,12 +132,12 @@ fun observe_captured() = () => local //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function lambda#0 @ -> Pure -//│ flow-analysis > function lambda$#0 @ -> Pure -//│ flow-analysis > function lambda$#1 @ -> Pure -//│ flow-analysis > function observe_captured#0 @ -> Pure -//│ flow-analysis > call lambda$@result @ -> Pure -//│ flow-analysis > call lambda@result @ -> Pure +//│ flow-analysis > function lambda$⁰#0 @ -> Pure +//│ flow-analysis > function lambda$⁰#1 @ -> Pure +//│ flow-analysis > function lambda⁰#0 @ -> Pure +//│ flow-analysis > function observe_captured⁰#0 @ -> Pure +//│ flow-analysis > call lambda$⁰@result⁰ @ -> Pure +//│ flow-analysis > call lambda⁰@result¹ @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< // * Observing a mutable state is an effect. @@ -147,7 +147,7 @@ set state = 42 fun observe_mutable() = state //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe_mutable#0 @ -> UnsafeEta +//│ flow-analysis > function observe_mutable⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = 42 let state = 0 @@ -155,7 +155,7 @@ fun observe_mutable() = state set state = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe_mutable#0 @ -> UnsafeEta +//│ flow-analysis > function observe_mutable⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = 42 @@ -168,8 +168,8 @@ let state = [0] fun observe_element() = state.[0] //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe_element#0 @ -> UnsafeEta -//│ flow-analysis > function observe_field#0 @ -> UnsafeEta +//│ flow-analysis > function observe_element⁰#0 @ -> UnsafeEta +//│ flow-analysis > function observe_field⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = [0] @@ -183,8 +183,8 @@ fun observe_local_element() = let local = [0] local.[0] //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe_local_element#0 @ -> UnsafeEta -//│ flow-analysis > function observe_local_field#0 @ -> UnsafeEta +//│ flow-analysis > function observe_local_element⁰#0 @ -> UnsafeEta +//│ flow-analysis > function observe_local_field⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -196,8 +196,8 @@ fun observe_alias_element(xs) = let local = xs local.[0] //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function observe_alias_element#0 @ -> UnsafeEta -//│ flow-analysis > function observe_alias_field#0 @ -> UnsafeEta +//│ flow-analysis > function observe_alias_element⁰#0 @ -> UnsafeEta +//│ flow-analysis > function observe_alias_field⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -211,8 +211,8 @@ fun rec_spread_local() = let obj = { value: 42 } {...obj} //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function rec_spread_local#0 @ -> UnsafeEta -//│ flow-analysis > function tup_spread_local#0 @ -> UnsafeEta +//│ flow-analysis > function rec_spread_local⁰#0 @ -> UnsafeEta +//│ flow-analysis > function tup_spread_local⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< let xs = [42] fun tup_spread_nonlocal() = @@ -221,8 +221,8 @@ let obj = { value: 42 } fun rec_spread_nonlocal() = {...obj} //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function rec_spread_nonlocal#0 @ -> UnsafeEta -//│ flow-analysis > function tup_spread_nonlocal#0 @ -> UnsafeEta +//│ flow-analysis > function rec_spread_nonlocal⁰#0 @ -> UnsafeEta +//│ flow-analysis > function tup_spread_nonlocal⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ obj = {value: 42} //│ xs = [42] @@ -237,17 +237,17 @@ fun shared_captures() = set local = 42 [observe, mutate] //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate#0 @ -> UnsafeEta -//│ flow-analysis > function mutate$#0 @ -> Pure -//│ flow-analysis > function mutate$#1 @ -> UnsafeEta -//│ flow-analysis > function observe#0 @ -> UnsafeEta -//│ flow-analysis > function observe$#0 @ -> Pure -//│ flow-analysis > function observe$#1 @ -> UnsafeEta -//│ flow-analysis > function shared_captures#0 @ -> UnsafeEta -//│ flow-analysis > call mutate$@result @ -> Pure -//│ flow-analysis > call mutate@result @ -> UnsafeEta -//│ flow-analysis > call observe$@result @ -> Pure -//│ flow-analysis > call observe@result @ -> UnsafeEta +//│ flow-analysis > function mutate$⁰#0 @ -> Pure +//│ flow-analysis > function mutate$⁰#1 @ -> UnsafeEta +//│ flow-analysis > function mutate⁰#0 @ -> UnsafeEta +//│ flow-analysis > function observe$⁰#0 @ -> Pure +//│ flow-analysis > function observe$⁰#1 @ -> UnsafeEta +//│ flow-analysis > function observe⁰#0 @ -> UnsafeEta +//│ flow-analysis > function shared_captures⁰#0 @ -> UnsafeEta +//│ flow-analysis > call mutate$⁰@result⁰ @ -> Pure +//│ flow-analysis > call mutate⁰@result² @ -> UnsafeEta +//│ flow-analysis > call observe$⁰@result¹ @ -> Pure +//│ flow-analysis > call observe⁰@result³ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< @@ -256,7 +256,7 @@ let state = 0 fun mutate_if(cond) = if cond do set state = 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_if#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_if⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = 0 @@ -267,7 +267,7 @@ fun mutate_local_if(cond) = if cond do set local = 42 local //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_local_if#0 @ -> Pure +//│ flow-analysis > function mutate_local_if⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< @@ -278,7 +278,7 @@ fun mutate_loop(again) = set state = 42 set again = false //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_loop#0 @ -> UnsafeEta +//│ flow-analysis > function mutate_loop⁰#0 @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ state = 0 @@ -291,5 +291,5 @@ fun mutate_local_loop(again) = set again = false local //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function mutate_local_loop#0 @ -> Pure +//│ flow-analysis > function mutate_local_loop⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< diff --git a/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls b/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls index 228347fdd3..0c52417389 100644 --- a/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls +++ b/hkmc2/shared/src/test/mlscript/opt/EtaEffects.mls @@ -10,8 +10,8 @@ let state = 0 fun effect() = set state += 42 //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function effect#0 @ -> UnsafeEta -//│ flow-analysis > call +@result @ -> Pure +//│ flow-analysis > function effect⁰#0 @ -> UnsafeEta +//│ flow-analysis > call +⁰@result⁰ @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< @@ -27,12 +27,12 @@ fun node() = leaf node()() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf#0 @ -> Pure -//│ flow-analysis > function node#0 @ -> Pure -//│ flow-analysis > function pure#0 @ -> Pure -//│ flow-analysis > call baseCall@result @ -> Pure -//│ flow-analysis > call node@result @ -> Pure -//│ flow-analysis > call pure@result @ -> Pure +//│ flow-analysis > function leaf⁰#0 @ -> Pure +//│ flow-analysis > function node⁰#0 @ -> Pure +//│ flow-analysis > function pure⁰#0 @ -> Pure +//│ flow-analysis > call baseCall⁰@result⁰ @ -> Pure +//│ flow-analysis > call node⁰@result¹ @ -> Pure +//│ flow-analysis > call pure⁰@result² @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > node⁰#0 @ : [0, 0] @@ -48,11 +48,11 @@ fun node() = leaf node()() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf#0 @ -> Pure -//│ flow-analysis > function node#0 @ -> UnsafeEta -//│ flow-analysis > call baseCall@result @ -> Pure -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call node@result @ -> UnsafeEta +//│ flow-analysis > function leaf⁰#0 @ -> Pure +//│ flow-analysis > function node⁰#0 @ -> UnsafeEta +//│ flow-analysis > call baseCall⁰@result⁰ @ -> Pure +//│ flow-analysis > call effect⁰@result² @ -> UnsafeEta +//│ flow-analysis > call node⁰@result¹ @ -> UnsafeEta //│ flow-analysis > <<< effect-analysis results <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > <<< eta-expansion targets shapes <<< @@ -70,14 +70,14 @@ fun pure() = 42 fun node() = leaf_1 node()()() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_1#0 @ -> Pure -//│ flow-analysis > function leaf_2#0 @ -> Pure -//│ flow-analysis > function node#0 @ -> Pure -//│ flow-analysis > function pure#0 @ -> Pure -//│ flow-analysis > call baseCall@result @ -> Pure -//│ flow-analysis > call callPrefix@result @ -> Pure -//│ flow-analysis > call node@result @ -> Pure -//│ flow-analysis > call pure@result @ -> Pure +//│ flow-analysis > function leaf_1⁰#0 @ -> Pure +//│ flow-analysis > function leaf_2⁰#0 @ -> Pure +//│ flow-analysis > function node⁰#0 @ -> Pure +//│ flow-analysis > function pure⁰#0 @ -> Pure +//│ flow-analysis > call baseCall⁰@result¹ @ -> Pure +//│ flow-analysis > call callPrefix⁰@result⁰ @ -> Pure +//│ flow-analysis > call node⁰@result² @ -> Pure +//│ flow-analysis > call pure⁰@result³ @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > node⁰#0 @ : [0, 0, 0] @@ -95,13 +95,13 @@ node()()() fun node() = leaf_1 node()()() //│ flow-analysis > >>> effect-analysis results >>> -//│ flow-analysis > function leaf_1#0 @ -> UnsafeEta -//│ flow-analysis > function leaf_2#0 @ -> Pure -//│ flow-analysis > function node#0 @ -> Pure -//│ flow-analysis > call baseCall@result @ -> UnsafeEta -//│ flow-analysis > call callPrefix@result @ -> Pure -//│ flow-analysis > call effect@result @ -> UnsafeEta -//│ flow-analysis > call node@result @ -> Pure +//│ flow-analysis > function leaf_1⁰#0 @ -> UnsafeEta +//│ flow-analysis > function leaf_2⁰#0 @ -> Pure +//│ flow-analysis > function node⁰#0 @ -> Pure +//│ flow-analysis > call baseCall⁰@result¹ @ -> UnsafeEta +//│ flow-analysis > call callPrefix⁰@result⁰ @ -> Pure +//│ flow-analysis > call effect⁰@result³ @ -> UnsafeEta +//│ flow-analysis > call node⁰@result² @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< //│ eta-expansion > >>> eta-expansion targets shapes >>> //│ eta-expansion > node⁰#0 @ : [0, 0] From 51e59e5b8a71a5c0c9fa49e1a56a4e361e7ed5ce Mon Sep 17 00:00:00 2001 From: Flandia Date: Sun, 4 Oct 2026 15:12:20 +0800 Subject: [PATCH 9/9] Mark external getters as unsafe for eta expansion --- .../hkmc2/codegen/flowAnalysis/FlowAnalysis.scala | 2 +- .../test/mlscript/effect-analysis/Mutation.mls | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala index deff466c44..1cac3894c9 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/flowAnalysis/FlowAnalysis.scala @@ -1148,7 +1148,7 @@ class FlowConstraintsCollector( case refSite@FunRef(f, selectedFrom) => // ? It's a special case for module getters but I'm not sure if // ? this is good enough. It just conservatively marks it unsafe. - if preAnalyzer.res.funSymToFunDefn.get(f).exists(_.params.isEmpty) then markUnsafeEta() + if f.irFunDefn.fold(!f.isPure)(_.params.isEmpty) then markUnsafeEta() for qual <- selectedFrom do cc.constrain(processResult(qual), UnknownCons) funsToProdStratScheme.get(f) match diff --git a/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls b/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls index ad01e02ad7..fd0341f3cf 100644 --- a/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls +++ b/hkmc2/shared/src/test/mlscript/effect-analysis/Mutation.mls @@ -293,3 +293,18 @@ fun mutate_local_loop(again) = //│ flow-analysis > >>> effect-analysis results >>> //│ flow-analysis > function mutate_local_loop⁰#0 @ -> Pure //│ flow-analysis > <<< effect-analysis results <<< + + +// * Regressions + +// * A getter from an earlier block is unsafe. +module M with + fun get = set state = 42 +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > <<< effect-analysis results <<< +//- +fun node() = M.get +//│ flow-analysis > >>> effect-analysis results >>> +//│ flow-analysis > function node⁰#0 @ -> UnsafeEta +//│ flow-analysis > <<< effect-analysis results <<< +