scala - 对隐式对象或值中的参数类型进行抽象?

标签 scala abstraction implicit

考虑隐式对象的这种应用

trait Splitter[A,B,C] {
   def split(list: List[C]):(List[A],List[B])
}

implicit object PairSplitter extends Splitter[Int, String, Pair[Int,String]] {
   override def split(list: List[Pair[Int,String]]):(List[Int],List[String]) =
     (list.collect{case (a,_) => a}, list.collect{case (_,b) => b})
}

implicit object EitherSplitter extends Splitter[Int, String, Either[Int,String]] {
   override def split(list: List[Either[Int,String]]):(List[Int],List[String]) =
     (list.collect{case Left(a) => a}, list.collect{case Right(b) => b})
}

def splitList[A,B,C](list:List[C])(implicit splitter:Splitter[A,B,C]):(List[A],List[B]) = splitter.split(list)

println(splitList(List((1,"one"),(2,"two"))).isInstanceOf[(List[Int],List[String])])
println(splitList(List[Either[Int,String]](Left(42),Right("two"))).isInstanceOf[(List[Int],List[String])])
//println(splitList(List(1,2,3,4))) //won't compile

它有效,但显然不是非常有用。为示例中的 Int 和 String 这样的具体类型编写此代码没有问题,但我看不出有什么方法可以编写一个隐式对象或对 A 和 B 进行抽象的 val。

这可以做到吗?如何做到?如果没有,期望具有这种能力的语言扩展是否合理?

最佳答案

Scala 的值(即 vals 和对象)是单态,因此如果您坚持隐式是值,则没有直接的方法来获得您想要的东西。

但如果它们不必是值,则有一个直接的替代方案:您可以使用可以多态的东西,隐式方法

implicit def pairSplitter[A, B] = new Splitter[A, B, Pair[A, B]] {
  override def split(list: List[Pair[A, B]]) : (List[A], List[B]) =
    (list.collect{case (a,_) => a}, list.collect{case (_,b) => b})
} 

REPL session ...

scala> splitList(List(("foo",2.0),("bar",3.0)))
res5: (List[java.lang.String], List[Double]) = (List(foo, bar),List(2.0, 3.0))

关于scala - 对隐式对象或值中的参数类型进行抽象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4814015/

相关文章:

scala - "Deferred inline method ` 富 ` in trait ` 富 ` cannot be invoked": Pairs

scala - 使用 apache spark 自动运行任务

scala - 案例类作为集合的 "wrapper"类。 map/foldLeft/怎么样

sql-server - 将数据从 MS SQL 表加载到 snappyData

kotlin - 在 Kotlin 中,抽象函数的默认参数值是否继承?

scala - 案例类和同伴的不同顺序的隐式解析

scala - 在 Scala 中的 firstCompletedOf 中需要什么是隐式的

scala - 喷雾.io : When (not) to use non-blocking route handling?

c - boolean 抽象 C 程序

perl - 我应该如何重组大型 Perl 脚本?