2016-04-24 79 views
0

我是新来的Scala,并试图学习不同的功能。 我试图在一个trait中声明一个curried函数(它带有两个不同的参数),一半在扩展类中实现它,然后允许用户调用只传递第二个参数的函数。如何启用咖喱功能继承,然后部分应用

事情是这样的:

这里声明了一个咖喱功能的特点:

trait MetricGenerator[T] { 
    def NextMetricCurrying(generateVal: =>Future[MetricValue[T]])(target: ActorRef): Unit = { 
     generateVal onSuccess {case mv:MetricValue[T] => println(target.path.name + " | "+ mv.toString)} 
    } 
} 

现在,我想延长一类具有这种特质,那么“半”所传递实现它(它的第一个函数参数),这样这个类的用户就会像调用普通函数一样调用它(而不是curried)。

我已经试过这样的事情:

class MemoryReader extends MetricGenerator[Long]{ 

    NextMetricCurrying({ 
    val p = Promise[MetricValue[Long]] 
     builder(sigar => sigar.getMem) onSuccess { 
     case Success(mem) => p.success(MetricValue[Long](category, key, computerId, mem.getFree/
     1024/1024)) 
     } 
     p.future 
     }) 
} 

但它不工作。

任何想法?

回答

1

一旦部分应用功能只有第一个参数,你会得到一个ActorRef => Unit。如果这就是你想要公开的功能,那就需要分配它。

class Foo extends MetricGenerator[Long] { 
    val preparedFun: ActorRef => Unit = NextMetricCurrying(???) 
    // note the form A => B 
} 

val bar = new Foo 
bar.preparedFun(anActorRef) 

请注意,如果你想确保preparedFun是可调用的,只要你有一个MetricGenerator例如,您可以重构如下。

trait MetricGenerator[T] { 
    protected def NextMetricCurrying(a: => Future[MetricValue[T]])(b: ActorRef): Unit 

    val preparedFun: ActorRef => Unit 
} 

要进一步混合继承和功能,它也可以定义如下。

trait MetricGenerator[T] { 
    protected def NextMetricCurrying(a: => Future[MetricValue[T]])(b: ActorRef): Unit 
    def nextValue: Future[MetricValue[T]] 

    final def preparedFun: ActorRef => Unit = NextMetricCurrying(nextValue) 
} 
+0

tnx,很清楚。一个问题 - 在第二次重构中,prepareFun可调用tnx给MetricGenerator impl。在第一个片段?或者是由于我错过了一些其他的事情? – barakcaf

+1

由于子类需要实现(而不是“手动”部分应用于子类)的'nextValue',部分应用了'NextMetricCurrying'。 – cchantep