2014-11-06 33 views
0

我想結合2斯卡拉功能到第3與andThen但我遇到類型系統的問題。斯卡拉與泛型的函數組合

下面是代碼:

object Test{ 

    def process1[T](in : List[T]) : List[T] = in 

    def process2[T](in : List[T]) : List[T] = in 

    //this works fine but you have to read it inside out 
    def combined2[T](in : List[T]) : List[T] = process2(process1(in)) 

    //this also works but at the cost of creating a new function every time 
    def combined3[T](in : List[T]) : List[T] = { 
    (process1[T] _ andThen process2[T] _)(in) 
    } 

    //this doesn't work. it is a function List[Nothing] => List[Nothing] 
    val combined = process1 _ andThen process2 _ 

    def main(s : Array[String]) { 
    val input : List[Int] = List(1,2,3) 
    val out1 : List[Int] = process1(input) 

    val combinedOut2 : List[Int] = combined2(input) 

    val combinedOut3 : List[Int] = combined3(input) 

    //this will not compile as combined is [List[Nothing] => List[Nothing] 
    //val combinedOut : List[Int] = combined(input) 
    } 
} 

有一個很好的方式來獲得的combined值從List[T]一個功能List[T]或這是與類型擦除一個根本性的問題?

+1

這是斯卡拉型系統的根本問題。我建議你從http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/開始閱讀第2和3部分。無形狀多態函數可以是一個解決方案 – 2014-11-06 06:03:15

回答

1

不知道這是很好的,但combined3可以縮短爲:功能情況的

def combined3[T] = process1[T] _ andThen process2[T] _ 

創建每次可以針對每種情況進行優化:

val combinedInt = combined3[Int] 

combinedInt(input) 
0

您可以結合功能這樣,它更清潔

implicit class FunctionCombiner[T, U](fn: T => U) { 
    def &&&(f: T => U): T => U = { 
     (t: T) => { 
      fn(t); f(t) 
     } 
    } 
} 

在此之後,您可以運行stat對此語句,如:

val f1 = (i: Int) => println((1*i).toString) 
val f2 = (i: Int) => println((2*i).toString) 
val f3 = (i: Int) => println((3*i).toString) 

val f = f1 &&& f2 &&& f3 

f(5) 

這將產生的結果:

5 
10 
15