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

Scala DSL #20

Open
w4n9H opened this issue Aug 10, 2018 · 0 comments
Open

Scala DSL #20

w4n9H opened this issue Aug 10, 2018 · 0 comments
Labels
Java Java系,比如Scala,Clojure,Spark等

Comments

@w4n9H
Copy link
Owner

w4n9H commented Aug 10, 2018

Scala DSL

DSL(Domain-specific language)

领域特定语言,针对一个特定的领域,具有受限表达性的一种计算机程序语言,比如正则表达式、SQL等等。

简单来说就是把一些非常复杂的过程,抽象出来,使用非常简单易懂的方式表达出来。

scala有一些特性可方便的支持DSL开发:函数curry化、隐式转换、infix notationsuffix notation 等。

简易DSL实现

class Expr(v: Any) {  //Any类型接收Int,String,Bool三种类型
  def len = v match {
    case s:String => s.length()
    case _ => -1
  }
  def asBool = v match {
    case i:Int => i != 0
    case b:Boolean => b
    case s:String => s != null && s.length() != 0
    case _ => false
  }
  def in(args: Any*) = args.exists(arg => arg == v)  //*获取可变参数
  def notin(args: Any*) = !args.exists(arg => arg == v)
  def and(that: Expr) = this.asBool && that.asBool
  def or(that: Expr) = this.asBool || that.asBool
}

object DSLDemo1 {
  //下面三个隐式转换,把Int,String,Bool都转换成Expr类型
  implicit def int2Expr(x:Int) = new Expr(x)
  implicit def str2Expr(x:String) = new Expr(x)
  implicit def bool2Expr(x: Boolean) = new Expr(x)
  def main(args: Array[String]): Unit = {
    println("abc" in ("abc", 1, 2))
    println("abc" notin ("acb", 1, 2))
    println("abc" len)
  }
}

使用DSL实现一个Web路由

// scala web framework router
// GET on "/foo" to Application.foo
// GET.on("/foo").to(Application.foo)
// Route[Int](RouteDef(GET, "/foo"), Application.foo)
// code consult http://colobu.com/2016/05/24/scala-dsl-tutorial-writing-web-framework-router/


sealed trait Method {
  def on[R](routeDef: RouteDef[R]): R = routeDef.with_method(this)
}
case object ANY extends Method
case object GET extends Method
case object POST extends Method

sealed trait RouteDef[Self] {
  def with_method(method: Method): Self
  def method: Method
  def elems: String
}

case class Out(state_code:Int = 200, body:String = "Success") {
  def get_state():Int = state_code
  def get_body():String = body
}

case class RouteDef0(method: Method, elems: String) extends RouteDef[RouteDef0] {
  def with_method(method: Method):RouteDef0 = {
    RouteDef0(method, elems)
  }
  def to(f0: () => Out) = Route0(this, f0)
}

sealed trait Route[RD] {
  def routeDef: RouteDef[RD]
}

case class Route0(routeDef: RouteDef0, f0: () => Out) extends Route[RouteDef0] {
  def run():Unit = {
    val method = routeDef.method
    val path = routeDef.elems
    val response = f0()
    val state = response.get_state()
    val body = response.get_body()
    println(s"Method: $method, Path: $path, Response State:$state, Body: $body")
  }
}

sealed trait AppInit {
  def init():Unit = println("App init")

}
case class Application() extends AppInit {
  def foo():Out = {
    init()
    Out(state_code=500, body="error")
  }
}


object WebDSL {
  implicit def stringToRouteDef(name: String):RouteDef0 = RouteDef0(ANY, name)

  def main(args: Array[String]): Unit = {
    val web = Application()
    val x = GET on "/foo" to web.foo
    println(x.run())
  }
}
@w4n9H w4n9H added the Java Java系,比如Scala,Clojure,Spark等 label Aug 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Java Java系,比如Scala,Clojure,Spark等
Projects
None yet
Development

No branches or pull requests

1 participant