0

我需要一个类型 Union 来强制限制类型,所以按照这里的答案,我将我的 Union 定义为:

sealed trait Value[T]
object Value{
  implicit object NumberWitness extends Value[Int]
  implicit object StringWitness extends Value[String]
}

现在,我如何创建由这种类型联合参数化的列表或类?有可能这样做吗?我在 repl 中尝试了以下语法,但没有任何运气:

scala> import Value._
import Value._

scala> def list[V: Value] = List("hello", 1)
list: [V](implicit evidence$1: Value[V])List[Any]

scala> list
<console>:18: error: ambiguous implicit values:
 both object NumberWitness in object Value of type Value.NumberWitness.type
 and object StringWitness in object Value of type Value.StringWitness.type
 match expected type Value[V]
       list
       ^

或者是否可以使用scalaz或cats等高级FP库来做到这一点?

4

1 回答 1

2

这称为类型类,而不是类型联合。它们旨在允许您编写与或 一起使用的方法,例如IntString

def listOfValues[V: Value](x: V) = List(x)
listOfValues(1) // works
listOfValues("") // works
listOfValues(0.0) // doesn't work
listOfValues(1, "") // doesn't work

不允许混合不同的类型。

可以使用存在类型来做到这一点,例如

case class WithValue[V: Value](x: V)
object WithValue {
  implicit def withValue[V: Value](x: V) = WithValue(x)
}

def list = List[WithValue[_]]("hello", 1)

但我不建议实际这样做。很可能有更好的方法来解决您的问题。

特别是,考虑简单地使用

// not sealed if you need to add other types elsewhere
// can be Value[T] instead
sealed trait Value 
case class IntValue(x: Int) extends Value
case class StringValue(x: Int) extends Value

// add implicit conversions to IntValue and StringValue if desired
List(StringValue("hello"), IntValue(1))
于 2016-07-05T17:24:24.507 回答