2017-04-05 57 views
1

我该如何完成这项工作?我手头的任务是有点复杂,但它归结为:多态函数中的Scala自动类型推断

object Z { 
    class B extends Function1[Int, Int] { 
    def apply(i: Int): Int = i 
    } 

    def compose[T <: Function1[X, X], X](fcts: List[T]): Function1[X, X] = { 
    fcts.reduce(_ andThen _) 
    } 

    def test() = { 
    val fcts = List.empty[B] 

    // Unspecified type parameter X 
    val composed: Function1[Int, Int] = compose[B](fcts) 
    } 
} 

我不知道如何界定“撰写”功能,能够接收一些具体的B类和自动推断依赖类型X

回答

2

Scala编译器在尝试推断像您一样的多个类型参数级别时表现不佳。相反,删除T <: Function1[X, X]会更简单,只需要一个表示Function1的参数和返回类型的类型参数。

def compose[A](fcts: List[Function1[A, A]]): Function1[A, A] = { 
    fcts.reduce(_ andThen _) 
} 

编译器将有一个更容易的时间简单地推断A,而不是试图找出与TX是,当XT类型的一部分。

val a: Int => Int = _ + 10 
val b: Int => Int = _ * 2 
val c: Int => Int = _ - 3 

scala> val f = compose(List(a, b, c)) 
f: Int => Int = scala.Function1$$Lambda$1187/[email protected] 

scala> f(2) 
res1: Int = 21 

请注意,reduce将抛出一个空函数的例外。

+0

确定它是一个解决方案..不完全是我会喜欢,虽然..没有其他选择使用forSome或其他Scala技巧?事情是,我的作品并不完全收到一个List [B](或Function1的列表)..)它比这更复杂一点。 –

+0

@MichelLemay您可能可以在不同的情况下做一些不同的事情,但在这种情况下,我没有看到类型推断的不足。 –