Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[data] Extensible ADTs #1071

Open
road21 opened this issue Feb 8, 2025 · 0 comments
Open

[data] Extensible ADTs #1071

road21 opened this issue Feb 8, 2025 · 0 comments

Comments

@road21
Copy link
Contributor

road21 commented Feb 8, 2025

We have Record that can be used to describe product data types via intersection types.
I am wondering, can we generalize it to support sum types via union types? Like iron use intersection types for AND constraints, union types for OR constraint.

For example:

type circle = "radius" ~ Double
type square = "length" ~ Double
type rectangle = "width" ~ Double & "height" ~ Double
type triangle = "_1" ~ Double & "_2" ~ Double & "_3" ~ Double
type shape = ("typ" ~ "circle" & circle) | ("typ" ~ "square" & square) |
  ("typ" ~ "rectangle" & rectangle) | ("typ" ~ "triangle" & triangle)

def area(shape: ADT[shape]): Double =
  shape.typ: "circle" | "square" | "rectangle" | "triangle" // type of common fields derives via union type
  // shape.radius is not compiling
  shape match
    case Like[circle](c)    => c.radius * c.radius * math.Pi
    case Like[square](s)    => s.length * s.length
    case Like[rectangle](r) => r.width * r.height
    case Like[triangle](t) =>
      val p = (t._1 + t._2 + t._3) / 2
      math.sqrt((p - t._1) * (p - t._2) * (p - t._3))
    // exhaustiveness can potentially be checked by macro

println(area("typ" ~ "circle" & "radius" ~ 1.0))
// area("radius" ~ 1.0) // is not compiling

I have roughly implemented macro and ADT class to make this example compiling:
https://github.com/road21/extensible-adts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant