kengorab/abra-lang

Generic enums

Closed this issue · 1 comments

I should be able to declare generic enum types:

enum List<T> {
  Cons(value: T, next: List<T>)
  Empty
}

val l = List.Cons(1, List.Cons(2, List.Empty))

Note that the value of List.Empty at the end will be of type List<T>, where the T is of type Type::Generic("T") until it gets inferred in the List.Cons constructor. If the above code was

val empty = List.Empty
val l = List.Cons(1, List.Cons(2, empty))

then it wouldn't work, because the declaration of empty won't have enough type information to resolve the T generic.

Here's a more complex example:

enum Either<L, R> {
  Left(value: L)
  Right(value: R)

  func getLeft(self): L? = match self {
    Left(value) => value
    Right => None
  }

  func getRight(self): R? = match self {
    Right(value) => value
    Left => None
  }
}

val left = Either.Left("hello") // type of `left` is `Either<String, Any>`
val right = Either.Right(1234) // type of `right` is `Either<Any Int>`

This is mostly implemented - I don't currently have a way of representing the Either type without manually specifying the generics in the constructor call, since inference doesn't backtrack (yet)