Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 隐式参数";“链接”;用于DSL_Scala_Dsl - Fatal编程技术网

Scala 隐式参数";“链接”;用于DSL

Scala 隐式参数";“链接”;用于DSL,scala,dsl,Scala,Dsl,我有一个想法(模糊的),以这种方式传递(或链接)一些隐式值,而不是将参数引入blockf: def block(x: Int)(f: => Unit)(implicit v: Int) = { implicit val nv = v + x f } def fun(implicit v: Int) = println(v) 如果我使用了类似的东西: implicit val ii: Int = 0 block(1) { block(2) { fun } } 它

我有一个想法(模糊的),以这种方式传递(或链接)一些隐式值,而不是将参数引入block
f

def block(x: Int)(f: => Unit)(implicit v: Int) = {
  implicit val nv = v + x
  f
}

def fun(implicit v: Int) = println(v)
如果我使用了类似的东西:

implicit val ii: Int = 0
block(1) {
  block(2) {
    fun
  }
}
它将打印
3

如果我可以说
def block(x:Int)(f:implicit Int=>Unit)

换句话说,我正在寻找一些设计模式,它允许我实现这个DSL:访问嵌套块中的一些累积值,但不显式地将其作为参数传递。可能吗?(
implicit
s不是必需的,只是一个强调我不想显式传递累加器的提示)。当然,上面的代码将打印0

编辑:可能的用法之一:以以下方式组合http路由

prefix("path") {
  prefix("subpath") {
    post("action1") { (req, res) => do action }
    get("action2") { (req, res) => do action }
  }
}

这里
post
get
将访问(如何?)累积的前缀,比如
List(“path”、“subpath”)
“/path/subpath/”
通过
implicit
传递状态是脏的,将导致意外的、难以追踪的错误。您要做的是构建一个函数,该函数的组合方式可以使嵌套调用在某个操作上累积,而其他任何操作都使用该值来执行该函数

case class StateAccum[S](init: S){
  val op: S => S
  def flatMap[A <: S](f: S => StateAccum[A]) ={
    val StateAccum(out) = f(s)
    StateAccum(op(init, out))
  }
  def apply(f: S => A) = f(init)
}
考虑为此使用。它使用起来非常简单,而且线程安全:

val acc: DynamicVariable[Int] = new DynamicVariable(0)

def block(x: Int)(f: => Unit) = {
  acc.withValue(acc.value + x)(f)
}

def fun = println(acc.value)

嗯,这在其他情况下可能有一些实际用途,但在我的情况下,我想要一个DSL,它允许嵌套
f
,并在那里使用一些值,比如
block(1){使用累积值的某物;block(2){使用累积值的某物;}
<用于的代码>不适用于此。请解释如何使用
映射器
?还是进不去it@dmitry没关系,我的for comp版本不会满足你的要求。但是,对它的编辑将被删除。它确实涉及“魔法”。@dmitry我正在将其纳入类型级别的“魔法”。它通过隐式优先级工作。您将“apply”更改为具有隐式值,并基于函数的返回类型,它将按照您想要的方式“工作”。即使在这种情况下,我也不希望每个块
f
都需要处理累加器。我只是希望它能以某种方式被访问。比如它是隐式的或者某个属性,
f
可以访问,但只有在需要时才可以访问。不是显式参数。这正是我需要的,谢谢!从未听说过:)
val acc: DynamicVariable[Int] = new DynamicVariable(0)

def block(x: Int)(f: => Unit) = {
  acc.withValue(acc.value + x)(f)
}

def fun = println(acc.value)