Skip to content

Instantly share code, notes, and snippets.

@kitlangton
Created June 2, 2023 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kitlangton/39bf05eb376134853492f5a4ccba7650 to your computer and use it in GitHub Desktop.
Save kitlangton/39bf05eb376134853492f5a4ccba7650 to your computer and use it in GitHub Desktop.
package book
object WithoutTypeParams:
sealed trait Expr
case class IntExpr(int: Int) extends Expr:
def add(other: IntExpr): IntExpr = IntExpr(int + other.int)
case class BoolExpr(bool: Boolean) extends Expr
case class IfThenElseExpr(cond: BoolExpr, thenExpr: Expr, elseExpr: Expr) extends Expr
// if true then 1 + 2 else 0
val ifThenThreeElseZeroExpr: Expr =
IfThenElseExpr(
cond = BoolExpr(true),
thenExpr = IntExpr(1).add(IntExpr(2)),
elseExpr = IntExpr(0)
)
// We can't safely implement `add` on IfThenElseExpr because it might return an Int or a Bool.
// val cantFurtherAdd = ifThenThreeElseZeroExpr.add(IntExpr(3))
// Also: Expr
val badIfThen: Expr = IfThenElseExpr(BoolExpr(true), IntExpr(1), BoolExpr(false))
object WithTypeParams:
sealed trait Expr[A]
final case class IntExpr(int: Int) extends Expr[Int]
final case class AddExpr(lhs: Expr[Int], rhs: Expr[Int]) extends Expr[Int]
final case class BoolExpr(bool: Boolean) extends Expr[Boolean]
final case class IfThenElseExpr[A](cond: Expr[Boolean], thenExpr: Expr[A], elseExpr: Expr[A]) extends Expr[A]
extension (lhs: Expr[Int]) //
def add(rhs: Expr[Int]): Expr[Int] = AddExpr(lhs, rhs)
// if true then 1 + 2 else 0
val ifThenThreeElseZeroExpr: Expr[Int] =
IfThenElseExpr(
cond = BoolExpr(true),
thenExpr = AddExpr(IntExpr(1), IntExpr(2)),
elseExpr = IntExpr(0)
)
// We can safely implement `add` on IfThenElseExpr because it will always return an Int.
val canFurtherAdd = ifThenThreeElseZeroExpr.add(IntExpr(3))
// can't construct an invalid expression
// this will no longer compile
// val badIfThen: Expr[Int] = IfThenElseExpr(BoolExpr(true), IntExpr(1), BoolExpr(false))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment