2016-04-24 72 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