Created
January 18, 2026 23:03
-
-
Save kory33/258c2eecc01a925df2adc93561b0048a to your computer and use it in GitHub Desktop.
An exotic instance for Writer-like Eff datatype
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| enum Executable[Instr[_], ExitCode]: | |
| case Exit[I[_], EC]( | |
| code: EC | |
| ) extends Executable[I, EC] | |
| case NonEmpty[I[_], BranchIndex, EC]( | |
| headInstruction: I[BranchIndex], | |
| branches: BranchIndex => Executable[I, EC] | |
| ) extends Executable[I, EC] | |
| import Executable.* | |
| extension [F[_], A](exe: Executable[F, A]) | |
| def replaceExits[B]( | |
| replacementRule: A => Executable[F, B] | |
| ): Executable[F, B] = | |
| exe match | |
| case Executable.NonEmpty(head, rest) => | |
| // すべての分岐先について再帰的に置換を行っていく | |
| Executable.NonEmpty(head, b => rest(b).replaceExits(replacementRule)) | |
| case Executable.Exit(ec) => | |
| // 置換個所(Exitノード)に到達したので置換する | |
| replacementRule(ec) | |
| enum WriteOne[Res, BI]: | |
| case Output[R](result: R) extends WriteOne[R, Unit] | |
| type WriteInstr[R] = [A] =>> WriteOne[R, A] | |
| extension [Res, A](exe: Executable[WriteInstr[Res], A]) | |
| // プログラム全体のexit codeを(プログラム構造を覗くことで)取り出す | |
| def extractResult: A = | |
| exe match | |
| case Exit(a) => a | |
| case NonEmpty(WriteOne.Output(_), branches) => branches(()).extractResult | |
| def swapMap[B](rule: A => Executable[WriteInstr[Res], B]) = | |
| val nextProg = rule(exe.extractResult) | |
| val overallRes = nextProg.extractResult | |
| nextProg.replaceExits(_ => exe.replaceExits(_ => Exit(overallRes))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment