{"id":18864465,"url":"https://github.com/marcosh/crem","last_synced_at":"2026-02-12T14:11:47.330Z","repository":{"id":65225286,"uuid":"587694172","full_name":"marcosh/crem","owner":"marcosh","description":"Compositional Representable Executable Machines","archived":false,"fork":false,"pushed_at":"2025-11-20T17:00:46.000Z","size":599,"stargazers_count":122,"open_issues_count":19,"forks_count":8,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-01-14T07:25:42.636Z","etag":null,"topics":["hacktoberfest","haskell","nix","state-machine"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcosh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-01-11T11:09:23.000Z","updated_at":"2025-12-14T01:04:27.000Z","dependencies_parsed_at":"2024-12-22T23:07:44.164Z","dependency_job_id":"4af43955-84ec-4fd2-a3fd-20dc2f164b8f","html_url":"https://github.com/marcosh/crem","commit_stats":{"total_commits":150,"total_committers":5,"mean_commits":30.0,"dds":"0.10666666666666669","last_synced_commit":"102abe03c527460822f5d87fb064e680b9fccf60"},"previous_names":["tweag/crem"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/marcosh/crem","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcosh%2Fcrem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcosh%2Fcrem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcosh%2Fcrem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcosh%2Fcrem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcosh","download_url":"https://codeload.github.com/marcosh/crem/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcosh%2Fcrem/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29368026,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-12T08:51:36.827Z","status":"ssl_error","status_checked_at":"2026-02-12T08:51:26.849Z","response_time":55,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["hacktoberfest","haskell","nix","state-machine"],"created_at":"2024-11-08T04:41:47.142Z","updated_at":"2026-02-12T14:11:47.324Z","avatar_url":"https://github.com/marcosh.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [crem](https://github.com/tweag/crem)\n\n\u003cimg src=\"https://raw.githubusercontent.com/tweag/crem/main/logo/crem-transparent.png\" width=\"200\"\u003e\n\n![CI status](https://github.com/tweag/crem/actions/workflows/ci.yml/badge.svg)\n\n`crem` stands for **c**ompositional **r**epresentable **e**xecutable **m**achines.\n\nIt allows defining state machines (Mealy machines in fact), composing them to build bigger machines out of smaller ones and then running them and drawing their flow and their state space.\n\n## What can you do with `crem`\n\n### Defining state machines\n\n`crem` allows you to define state machines so that you can enforce which state transitions are actually allowed by your machine.\n\nIf you try to implement a machine by running a transition which is not allowed, you will get a compilation error.\n\nMore details on how to define a machine at [How to create a machine](/docs/how-to-create-a-machine.md).\n\n### Composing state machines\n\n`crem` allows you to compose machines together to build more complex ones, proving a compositional language to implement state machines.\n\nMore details on how to compose machines at [How to compose machines](/docs/how-to-compose-machines.md)\n\n### Rendering a state machine\n\nThanks to the information on the allowed transitions `crem` collects when you define a machine, it is able to produce a graphical representation of the flow and the state space of your machine.\n\nOne example of such an output is\n\n![risk manager flow](https://mermaid.ink/svg/pako:eNqlVF1PwjAU_SvkPmkyCGCBbQ8mCvqkxkj0wSwhzXad1a4lXUdAsv9u9-HcCMgMfepOz73n3PbubsGXAYILsaYaZ4yGikbd1dATHbNysEPDUGGY7bYFnK0KXDzIGdX0BZXG9b7zqeQcfY3Bc4yqJfVOUjFDTRmPb5mK9eGQJ_SRrTCYKgyYvk4U0iQTORJWKV1x_renenmdbvfyxMqa1EMJ29ffLvGpt7TfzyH3R--0hZ1_5E7rzbqUnPmbeqcWyOLsvMH-bepMqOAUJ2WGhn5DQckPY4VJ0VCp0MWciZDjYwXs8bqjXlHrOpEvhU91XaSEdmupOcrSlSywIEIVURaY3ztP4oF-xwg9cM02oOrTA0-khpcsA6N4Y95CKnDfKI_RAppoOd8IH1ytEvwhlSOiYi2peJWy8Q3uFtbgkv6oN7ZtZ0xscjEZWbABdziY9IjjODaZkMFw0HdIasFXHt_vGQrmFu6LkZRPpvQbS36R_g)\n\nMore details on how to render a machine at [How to render a machine](/docs/how-to-render-a-machine.md)\n\n### Running a machine\n\nLast but not the least, you can also execute a machine, providing inputs to it and receiving the emitted outputs.\n\nMore details on how to run a machine at [How to run a machine](/docs/how-to-run-a-machine.md)\n\n### Want to know more?\n\nFurther documentation can be found in the [docs](/docs) folder.\n\nThe [examples](/examples) folder contains a lot of examples, from simple machines to complex ones describing entire workflows.\n\nI would recommend to check:\n\n- [TwoSwitchesGate.lhs](/examples/Crem/Example/TwoSwitchesGate.lhs) if you want to see all the code which is needed to use the library with a quite detailed explanation.\n- [RiskManager](/examples/Crem/Example/RiskManager/) if you want to see how to use `crem` to [model your domain using state machines](http://marcosh.github.io/post/2021/10/27/ddd-state-machines.html) following the ideas coming from Domain Driven Design.\n- [Uno.hs](/examples/Crem/Example/Uno.hs) if you want to see how to structure a card game like [Uno](https://en.wikipedia.org/wiki/Uno_(card_game)), with an implementation ported from [UnoCore](https://github.com/thinkbeforecoding/UnoCore/blob/solution/Uno/Game.fs) by [@thinkb4coding@mastodon.social](https://functional.cafe/@thinkb4coding@mastodon.social).\n\nBe sure to check out also the [spec](/spec) folder, where all the tests of the application are included, to see in practice what you can do with `crem`.\n\n## Development\n\nThis is a Haskell Cabal project that uses Nix for development. Nix is optional but recommended.\n\n### environment\n\nA Nix shell is available with all the required tools. To enter the shell, issue\n\n```sh\n# default GHC\nnix develop\n\n# custom GHC\nnix develop .#ghc90\nnix develop .#ghc92\n```\n\nOr, without flakes:\n\n```sh\n# default GHC\nnix-shell\n```\n\n### GHC version\n\nThe project has a default GHC version that is specified in the flake. At the moment that version is 9.0, because the HLS plugin Wingman [currently only builds up to this version](https://github.com/haskell/haskell-language-server/issues/2971).\n\nIt is also possible to use other GHC versions to build the project and enter development shells. This allows us to easily test multiple versions.\n\n### Building\n\nIn a development shell, you can simply build the project with Cabal:\n\n```sh\ncabal build\n```\n\nThis provides us fast incremental builds, ease of debugging, etc.\n\nInside the development shell, you can also use the commands\n\n```sh\n# just build the project\nbuild-watch\n\n# execute also the tests\ntest-watch\n```\n\n### Haddock documentation\n\nYou can generate and see the [Haddock] documentation by running\n\n```sh\ncabal haddock --open\n```\n\n### Code formatting\n\nCode is formatted using [fourmolu](https://github.com/fourmolu/fourmolu) version 0.12.0.0.\n\n### Cabal flags\n\nWe have a `cabal` flag called `errors` which allows enabling `-Werror`. It has a default of `False`, so that warning are not turned into errors.\n\nIn development and CI we use the flag `-f errors` so that we can avoid any warning in the library code.\n\n### Changelog\n\nAll changes are tracked in the [`Changelog`](CHANGELOG.md).\n\n## Project setup\n\nYou can find more details on the project setup on [Setup.md](/Setup.md).\n\n## Known limitations\n\nThe project is still in its early stage and not everything is crafted to perfection.\n\nSome known limitations to the current state of the project are:\n- `crem` has not been tested on huge state machines. Compilation times might grow very rapidly.\n- the topologies which `crem` allows you to define need to be finite, and not particularly big, either. For example, it is not feasible to use `Int` as the type of vertices for a topology.\n- in its current state, the `StateMachine` type is not extensible. It has a predefined set of constructors, but maybe there are more which make sense and are not present yet.\n\nMoreover, for current bugs and feature requests, you can check the [open issues](https://github.com/tweag/crem/issues).\n\n## Credits\n\n![tweag logo](./logo/tweag.png)\n\nThe initial development of `crem` was funded by [Tweag](https://www.tweag.io/).\n\n## Contributions\n\nContributions are extremely welcome. If you have any idea on how to improve the library, its code or its documentation, feel free to open an [issue](https://github.com/tweag/crem/issues), create a [pull request](https://github.com/tweag/crem/pulls), or just contact directly one of the maintainers.\n\n## Logo\n\nThe `crem` logo was kindly generated by [craiyon](https://www.craiyon.com/).\n\n## Resources\n\nIf you want to know a bit more of `crem` and some ideas behind it, here are some additional resources you can check out:\n\n- [Domain modelling with state machines](http://marcosh.github.io/post/2021/10/27/ddd-state-machines.html), the first blog post where I started considering using composable state machines for DDD-like architectures.\n- [Composable Haskell state machines with `crem`](https://www.youtube.com/watch?v=cvbOG1I6wrU), if you prefer a video introducing `crem`.\n- [State machines with `crem`](https://hackmd.io/@CJO5VbycTsyzjGBytbwezQ/rkJliIjRj#/) the slide deck used for the above presentation.\n- [Crem: compositional representable executable machines](https://www.tweag.io/blog/2023-04-13-crem-state-machines/), a blog post explaining the main ideas of `crem`.\n- [Domain modelling with state machines](https://www.youtube.com/watch?v=UBnHpnss8Fg), a video describing the main ideas motivating `crem`.\n- [Crème de la Crem: Composable Representable Executable Machines](https://dl.acm.org/doi/10.1145/3609025.3609480?cid=99660990271), an academic paper describing the why and the how of `crem` (you can access it by clicking the link in [my blog](http://marcosh.github.io)).\n\n## Projects using Crem\n\n- [monadi-games-club](https://github.com/silky/monadic-games-club)\n- [blackjack](https://github.com/beefyhalo/blackjack)\n- [elevator](https://github.com/OlaoluwaM/elevator)\n\nIf you have a project which is using `Crem`, please let me know, or feel free to open a PR to add it to the list!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcosh%2Fcrem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcosh%2Fcrem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcosh%2Fcrem/lists"}