Scala捕获调用范围的所有含义?

时间:2014-07-08 04:03:08

标签: scala implicit implicit-parameters

假设我有一个范围A,其中定义了一些隐式值,以及一个使用这些隐式值的代码块c。我也有范围B,它具有兼容类型的含义,因此如果我将代码块c复制到B,它将编译并运行没有问题。当然,这很丑陋,因为我在两个地方复制c,所以我想将c移动到它自己的函数中。现在,c的函数签名必须如下所示:

def c(args...)(implicit implicitArgs...) = ...

其中implicitArgsc中使用的隐含值。鉴于某些框架(在我的情况下,Scalding)定义了许多含义,这里的签名很快就会失控。有没有语法说“在调用范围中携带所有隐含值”?或者有一个聪明的方法吗?

欢呼声, 杰夫

2 个答案:

答案 0 :(得分:0)

不确定这是否有效,但您可以尝试一下。您可以将implicits分组到容器对象中。

示例:假设您有XYZ类型的含义,并且您并不总是想要添加三个implicit每个方法的参数。假设您为那些定义容器对象:

class MyImplicits(val x:X, val y:Y, val z:Z)

为了允许自动创建MyImplicits包装器,您可以创建一个从单个implicits派生它的对象方法。同样,您定义了隐式的非包装方法:

object MyImplicits {
  implicit def wrap(implicit x:X, y:Y, z:Z):MyImplicits = new MyImplicits(x, y, z)
  implicit def unwrapX(implicit wrapper:MyImplicits):X = wrapper.x
  implicit def unwrapY(implicit wrapper:MyImplicits):Y = wrapper.y
  implicit def unwrapZ(implicit wrapper:MyImplicits):Z = wrapper.z
}

我们假设我们有这样的方法:

def foo(...)(implicit implicits:MyImplicits) = ...

以下内容应该有效:

implicit val implicitXIsInScope:X = ...
implicit val implicitXIsInScope:Y = ...
implicit val implicitXIsInScope:Z = ...
foo(...) // MyImplicits should automatically be created

同样,如果MyImplicits的实例处于隐式作用域,您应该能够调用任何需要隐式X实例的方法,而无需显式解包。

我没试过这个。请告诉我它是否有效!

答案 1 :(得分:0)

我找到了一种方法来解决隐含的args":

def myfunc(arg:Something)(implicit session:Otherthing):Unit = ....

val curriedFunc = myfunc(value)(_:Otherthing)

curriedFunc(valueOfOtherThing)

有关详细信息,请参阅http://www.codecommit.com/blog/scala/function-currying-in-scala

上的无曲面部分

注意:我是Scala的新手,我不了解所有最佳做法。