{"id":15060833,"url":"https://github.com/zhxxch/effectfulcode","last_synced_at":"2026-01-02T14:08:59.494Z","repository":{"id":250450568,"uuid":"833208204","full_name":"zhxxch/EffectfulCode","owner":"zhxxch","description":"algebraic effects for F#","archived":false,"fork":false,"pushed_at":"2024-08-01T02:12:37.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-21T22:35:12.477Z","etag":null,"topics":["algebraic-effects","computation-expressions","fsharp"],"latest_commit_sha":null,"homepage":"","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zhxxch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-24T15:08:12.000Z","updated_at":"2024-08-01T02:12:32.000Z","dependencies_parsed_at":"2024-07-30T08:08:53.764Z","dependency_job_id":null,"html_url":"https://github.com/zhxxch/EffectfulCode","commit_stats":null,"previous_names":["zhxxch/effectfulcode"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhxxch%2FEffectfulCode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhxxch%2FEffectfulCode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhxxch%2FEffectfulCode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhxxch%2FEffectfulCode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhxxch","download_url":"https://codeload.github.com/zhxxch/EffectfulCode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243701308,"owners_count":20333616,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algebraic-effects","computation-expressions","fsharp"],"created_at":"2024-09-24T23:05:14.225Z","updated_at":"2026-01-02T14:08:59.450Z","avatar_url":"https://github.com/zhxxch.png","language":"F#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Algebraic effects for F#\n\nThis library (EffectfulCode.fs) implements **one-shot algebraic effects** in F# using [F# 6 Resumable Code](https://learn.microsoft.com/dotnet/fsharp/whats-new/fsharp-6#resumable-code); (when possible,) effectful codes are compiled to highly efficient state machines.\n\nHow to using this library: see below demonstration.\n\n## Examples\n\n### Example 1\n\nrun `dotnet fsi -O example/example-1.fsx` to interact with this example program.\n\n```F#\n#load \"../src/EffectfulCode.fs\"\n\n// declear computation expression (CE) builder\nlet ef = new EffectfulCode.CodeBuilder()\nlet withHandler = new EffectfulCode.AddHandlerBuilder()\n\n// declear effects\ntype AskInputEffect = AskInput of string\ntype WriteLogEffect = WriteLog of string\ntype MultiplyEffect = Mul of float * float\ntype AddEffect = Add of float * float\n\n// define effectful code\nlet inline example1 () =\n    ef {\n        do! ef { yield WriteLog \"effectful code start\" }\n        let! x = ef { yield AskInput \"x = \" }\n        printfn \"variable x = %g\" x\n\n        let! y = ef { yield AskInput \"y = \" }\n        printfn \"variable y = %g\" y\n\n        let! xy = ef { yield Add(x, y) }\n        printfn \"x + y = %g\" xy\n\n        let! z = ef { yield AskInput \"z = \" }\n        printfn \"variable z = %g\" z\n\n        let! xyz = ef { yield Mul(xy, z) }\n        printfn \"(x + y) * z = %g\" xyz\n\n        do! ef { yield WriteLog \"effectful code about to return\" }\n\n        let xyz' = (x + y) * z\n        return (xyz, xyz')\n    }\n\n// define handlers\nlet inline h_log (WriteLog s) = ef { return printfn \"-- log: %s\" s }\n\nlet inline h_input (AskInput question) =\n    ef {\n        printf \"%s\" question\n        let input_str = System.Console.ReadLine()\n        let x = System.Double.Parse input_str\n        do! ef { yield WriteLog(sprintf \"resume `AskInput` with %g\" x) }\n        return x\n    }\n\nlet inline h_add (Add(x, y)) =\n    ef {\n        do! ef { yield WriteLog(sprintf \"resume `Add` with %g\" (x + y)) }\n        return x + y\n    }\n\nlet inline h_mul (Mul(x, y)) =\n    ef {\n        do! ef { yield WriteLog(sprintf \"resume `Mul` with %g\" (x * y)) }\n        return x * y\n    }\n// define alternative handlers\nlet inline h_add_tropical (Add(x, y)) =\n    ef {\n        do! ef { yield WriteLog(sprintf \"resume `Add` with %g\" (min x y)) }\n        return min x y\n    }\n\nlet inline h_mul_tropical (Mul(x, y)) =\n    ef {\n        do! ef { yield WriteLog(sprintf \"resume `Mul` with %g\" (x + y)) }\n        return x + y\n    }\n\n// add handlers\nwithHandler {\n    return example1 ()\n    yield h_input\n    yield h_add\n    yield h_mul\n    yield h_log\n} |\u003e fun f -\u003e f () |\u003e fun (a, a') -\u003e printfn \"(x + y) * z = %g (%g)\" a a'\n\n// add handlers(alternative syntax \u0026 different handlers)\nlet inline example1' () =\n    example1 () |\u003e withHandler{yield h_input}\n\nlet code = withHandler {\n    yield h_log\n    yield h_add_tropical\n    yield h_mul_tropical\n    return example1' ()\n}\n\ncode () |\u003e fun (a, a') -\u003e printfn \"(x + y) * z = %g (%g)\" a a'\n\n// trying to run effectful code with any unhandled effect raises an exception\nwithHandler {\n    return example1' ()\n    yield h_input\n    yield h_log\n    yield h_add_tropical\n    yield h_mul_tropical\n} |\u003e fun code -\u003e code () |\u003e fun (a, a') -\u003e printfn \"(x + y) * z = %g (%g)\" a a'\n\n```\n\n## Licence\n\nGPLv3\n\n## Annex 1 - about algebraic effects\n\nReadings:\n\n- Dan Abramov. [Algebraic Effects for the Rest of Us — overreacted](https://overreacted.io/algebraic-effects-for-the-rest-of-us/#a-function-has-no-color)\n- Nathanaël Courant. [Gagallium : Safely typing algebraic effects](https://gallium.inria.fr/blog/safely-typing-algebraic-effects/)\n- [A Neighborhood of Infinity: The Mother of all Monads](http://blog.sigfpe.com/2008/12/mother-of-all-monads.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhxxch%2Feffectfulcode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhxxch%2Feffectfulcode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhxxch%2Feffectfulcode/lists"}