{"id":26977193,"url":"https://github.com/tttardigrado/goadt","last_synced_at":"2026-05-01T09:31:36.980Z","repository":{"id":65438178,"uuid":"592316838","full_name":"tttardigrado/goadt","owner":"tttardigrado","description":"Algebraic Data Types generator for the Go programming language","archived":false,"fork":false,"pushed_at":"2023-01-26T13:48:31.000Z","size":5551,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-03T12:18:28.652Z","etag":null,"topics":["adt","algebraic-data-types","code-generator","functional-go","functional-programming","go-generate","golang","golang-tools","haskell"],"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/tttardigrado.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2023-01-23T13:24:40.000Z","updated_at":"2025-02-17T19:17:42.000Z","dependencies_parsed_at":"2023-02-13T20:16:15.947Z","dependency_job_id":null,"html_url":"https://github.com/tttardigrado/goadt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tttardigrado/goadt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tttardigrado%2Fgoadt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tttardigrado%2Fgoadt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tttardigrado%2Fgoadt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tttardigrado%2Fgoadt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tttardigrado","download_url":"https://codeload.github.com/tttardigrado/goadt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tttardigrado%2Fgoadt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32492107,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["adt","algebraic-data-types","code-generator","functional-go","functional-programming","go-generate","golang","golang-tools","haskell"],"created_at":"2025-04-03T12:18:35.673Z","updated_at":"2026-05-01T09:31:36.962Z","avatar_url":"https://github.com/tttardigrado.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoADT\n\n![Tests CI](https://github.com/tttardigrado/goadt/actions/workflows/tests.yml/badge.svg)\n![Build CI](https://github.com/tttardigrado/goadt/actions/workflows/build.yml/badge.svg)\n![License](https://img.shields.io/github/license/tttardigrado/goadt)\n\u003ca href=\"https://twitter.com/intent/tweet?text=Check out goadt, a Golang Algebraic Data Type generator written by %40_tardigrado_ in Haskell https%3A%2F%2Fgithub.com%2Ftttardigrado%2Fgoadt 😁\"\u003e\u003cimg src=\"https://img.shields.io/twitter/url?style=social\u0026url=https%3A%2F%2Fgithub.com%2Ftttardigrado%2Fgoadt\"\u003e\u003c/a\u003e\n\nAlgebraic data types generator for the Go programming language\n\n![Logo](./logo.png)\n\n## Tech stack\n* Haskell\n* Golang\n* Parsec\n* CmdArgs\n* Go-Sumtypes\n\n## Product types\nA product type `A x B` is a compounded type that combines one element from each of the types. According to the Curry-Howard isomorphism, it corresponds to the `AND` operation in intuitionistic logic.\n\nIn golang, we are going to represent product types as `structs`.\n\n```haskell\n-- haskell\ndata Tuple a b = Tuple\n  { x :: a\n  , y :: b\n  }\n```\n\n```go\n// golang\ntype Tuple[A, B any] struct {\n    x A\n    y B\n}\n```\n\n## Sum types\nA sum type `A + B` is a compounded type that requires one element from one of the types. According to the Curry-Howard isomorphism, it corresponds to the `OR` operation in intuitionistic logic.\n\nIn golang, we are going to represent product types as `interfaces`\n```haskell\n-- haskell\ndata Either a b\n  = Left a\n  | Right b\n```\n```go\n// go\ntype Either[A, B any] infterface {\n    implEither()\n}\n\ntype Left[A, B any] struct { a A }\nfunc (_ Left) implEither() {}\n\ntype Right[A, B any] struct { b B }\nfunc (_ Right) implEither() {}\n```\n\n## Using ADTs\n\nLet's start with an example of an ADT: `Opt`. This type represents the possibility of the non-existence of a value (in Haskell it's known as `Maybe`, but we will define an isomorphic `Opt` type)\n\n```haskell\n-- haskell\ndata Opt a\n  = None\n  | Some a\n```\n```go\n// go\ntype Opt[A any] interface { implOpt() }\n\n// Data Constructors Structs\ntype Some[A any] struct { V A }\ntype None[A any] struct {     }\n\n// Implement the interface\nfunc (_ Some[A]) implOpt() { }\nfunc (_ None[A]) implOpt() { }\n\n// Constructors\nfunc NewSome[A any](V A) Opt[A] { return Some[A]{ V: V } }\nfunc NewNone[A any](   ) Opt[A] { return None[A]{      } }\n```\n\nNow, let's see how to use it. In most functional programming languages (like Haskell, Ocaml and SML) ADTs can be used with `pattern matching`, but, unfortunately, go does not have that feature. The closest analog is a `type switch`.\n\n```haskell\n-- haskell\nmap :: (a -\u003e r) -\u003e Opt a -\u003e Opt r\nmap fn (Some v) = Some $ fn v\nmap fn  None    = None\n```\n\n```go\n// go\nfunc Map[A, R any](fn func(A) R, opt Opt[A]) (res Opt[R]) {\n\tswitch t := opt.(type) {\n\tcase Some[A]: res = NewSome(fn(t.V))\n\tcase None[A]: res = NewNone[R]()\n\t}\n\treturn\n}\n```\n\nIf you build your functions this way, [go-sumtype](https://github.com/BurntSushi/go-sumtype) can be used to check for the exhaustiveness of the type switches. \n\n## Using GoADT\nCheck the [examples](./examples/) directory to see how one could use `goadt` and `go generate` to automatically generate ADTs\n\n## References:\n1. [Go and Algebraic data types](https://eli.thegreenplace.net/2018/go-and-algebraic-data-types/) by Eli Bendersky\n2. [Sum Types in Go](https://www.jerf.org/iri/post/2917/) by Jeremy Bowers\n3. [Golang Tips #1: ADT](https://rguilmont.net/blog/2022-02-20-golang-generics-options/) by Romain Guilmont\n4. [Alternatives to sum types in Go](https://making.pusher.com/alternatives-to-sum-types-in-go/) by Will Sewell\n5. [Wikipedia's](https://en.wikipedia.org/wiki/Algebraic_data_type) article on ADTs\n6. [Algebraic Data Types in Haskell](https://serokell.io/blog/algebraic-data-types-in-haskell) by Gints Dreimanis \n7. [Why algebraic data types are important](https://www.youtube.com/watch?v=LkqTLJK2API) by Bartosz Milewski\n8. [go-sumtype](https://github.com/BurntSushi/go-sumtype) an exhaustiveness checker for sum types by Andrew Gallant\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftttardigrado%2Fgoadt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftttardigrado%2Fgoadt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftttardigrado%2Fgoadt/lists"}