Guest User

Untitled

a guest
Sep 14th, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.76 KB | None | 0 0
  1. object HigherOrderAbstractSyntax {
  2. /**
  3. * Let's write a language which supports:
  4. *
  5. * let i = 0
  6. * in while (i < 10) { i = i + 1 }
  7. */
  8. trait Expr[F[_]] {
  9. def intLit(value: Int): F[Int]
  10. def add(l: F[Int], r: F[Int]): F[Int]
  11. // Uses scala lambdas in input type
  12. def let[A, B](name: Symbol, value: F[A], body: F[A] => F[B]): F[B]
  13. def updateVar[A](name: Symbol, value: F[A]): F[A]
  14. def lessThan(l: F[Int], Right: F[Int]): F[Boolean]
  15. def while0[A](condition: F[Boolean], body: F[A]): F[Unit]
  16. }
  17. object Expr {
  18. def apply[F[_]](implicit F: Expr[F]): Expr[F] = F
  19. }
  20.  
  21. implicit class IntExprSyntax[F[_]](left: F[Int]) {
  22. def + (right: F[Int])(implicit F: Expr[F]): F[Int] = F.add(left, right)
  23. def < (right: F[Int])(implicit F: Expr[F]): F[Boolean] = F.lessThan(left, right)
  24. }
  25. def int[F[_]: Expr](i: Int): F[Int] = Expr[F].intLit(i)
  26. def let[F[_]: Expr, A, B](name: Symbol, value: F[A])(body: F[A] => F[B]): F[B] =
  27. Expr[F].let(name, value, body)
  28. def while0[F[_]: Expr, A](condition: F[Boolean])(body: F[A]): F[Unit] =
  29. Expr[F].while0(condition, body)
  30.  
  31. case class IState(value: Map[Symbol, Any]) {
  32. def addVariable(name: Symbol, v: Any): IState =
  33. copy(value = value + (name -> v))
  34.  
  35. def removeVariable(name: Symbol): IState =
  36. copy(value = value - name)
  37. }
  38.  
  39. import scalaz.zio._
  40.  
  41. // Look how in this program, 'i is defined in let, but than becomes a real
  42. // scala variable in the places where you want to use it.
  43. //
  44. // Variables in the DSL, have now become variables in scala as well. This
  45. // doesn't hold for the updateVar yet. This can be worked around, but if
  46. def program[F[_]: Expr]: F[Unit] =
  47. let('i, int(0))(i =>
  48. while0(i < int(10))(
  49. Expr[F].updateVar('i, i + int(1))
  50. )
  51. )
  52. }
Add Comment
Please, Sign In to add comment