Advertisement
Guest User

Untitled

a guest
May 26th, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.39 KB | None | 0 0
  1. package rs
  2.  
  3. import scala.language.higherKinds
  4.  
  5. import matryoshka.data._
  6. import matryoshka.implicits._
  7. import scalaz._, Scalaz._
  8.  
  9. trait Expr[A]
  10. case class NumLit[A](value: Int) extends Expr[A]
  11. case class Add[A](left: A, right: A) extends Expr[A]
  12. case class Div[A](num: A, denum: A) extends Expr[A]
  13. case class DivisionByZero(div: Div[Int])
  14.  
  15. object Expr {
  16. implicit val traverse: Traverse[Expr] = new Traverse[Expr] {
  17. def traverseImpl[G[_] : Applicative, A, B](expr: Expr[A])(f: A => G[B]): G[Expr[B]] = expr match {
  18. case NumLit(value) => (NumLit(value): Expr[B]).point[G]
  19. case Add(left, right) => (f(left) |@| f(right)) (Add(_, _))
  20. case Div(num, denum) => (f(num) |@| f(denum)) (Div(_, _))
  21. }
  22. }
  23. }
  24.  
  25.  
  26. object Main extends App {
  27.  
  28. def complexity(expr: Fix[Expr]): Int = expr.cata[Int] {
  29. case NumLit(value) => 1
  30. case Add(left, right) => 1 + Math.max(left, right)
  31. case Div(num, denum) => 1 + Math.max(num, denum)
  32. }
  33.  
  34. def incr(expr: Fix[Expr]): Fix[Expr] = expr.cata[Fix[Expr]] {
  35. case NumLit(value) => Fix(NumLit(value + 1))
  36. case other => Fix(other)
  37. }
  38.  
  39. type ErrorOr[A] = DivisionByZero \/ A
  40.  
  41. def eval(expr: Fix[Expr]): ErrorOr[Int] = expr.cataM[ErrorOr, Int] {
  42. case NumLit(value) => value.right
  43. case Add(left, right) => (left + right).right
  44. case d@Div(num, denum) => if (denum != 0) (num / denum).right else DivisionByZero(d).left
  45. }
  46.  
  47. def collect(a: Fix[Expr]): List[NumLit[_]] = a.cata[List[NumLit[_]]] {
  48. case n@NumLit(value) => List(n)
  49. case other => other.fold
  50. }
  51.  
  52. def gen(complexity: Int): Option[Fix[Expr]] = {
  53. complexity.anaM[Fix[Expr]][Option, Expr] {
  54. case 0 => None
  55. case 1 => Some(NumLit(1))
  56. case n => Some(Add(n - 1, n - 1))
  57. }
  58. }
  59.  
  60.  
  61. val expr: Fix[Expr] = Fix(Add(Fix(NumLit(5)), Fix(NumLit(10))))
  62. println("expr := " + expr)
  63. println("complexity := " + complexity(expr))
  64. println("incr := " + incr(expr))
  65. println("eval 1+1 := " + eval(Fix(Add(Fix(NumLit(1)), Fix(NumLit(1))))))
  66. println("eval 6/3 := " + eval(Fix(Div(Fix(NumLit(6)), Fix(NumLit(3))))))
  67. println("eval 5/0 := " + eval(Fix(Div(Fix(NumLit(5)), Fix(NumLit(0))))))
  68. println("collect := " + collect(Fix(Add(Fix(NumLit(1)), Fix(Add(Fix(NumLit(2)), Fix(NumLit(3))))))))
  69. println("gen(0) := " + gen(0).map(complexity))
  70. println("gen(1) := " + gen(1).map(complexity))
  71. println("gen(2) := " + gen(2).map(complexity))
  72. println("gen(3) := " + gen(3).map(complexity))
  73.  
  74. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement