在Scala中,我可以在编译时强制执行类型相等.例如:
case class Foo[A,B]( a: A, b: B )( implicit ev: A =:= B )
scala> Foo( 1, 2 )
res3: Foo[Int,Int] = Foo(1,2)
scala> Foo( 1, "2" )
<console>:10: error: Cannot prove that Int =:= java.lang.String.
Run Code Online (Sandbox Code Playgroud)
有没有办法强制执行类型A和类型B应该是不同的?
考虑一个通用函数:
def genericFn[T](fn: T => Boolean): Unit = {
// do something involves T
}
Run Code Online (Sandbox Code Playgroud)
是否可以限制T(在编译时)一个简单的类型,而不是类似的类型List[Int]?
我想要解决的基础问题是这样的:
var actorReceive: Receive = PartialFunction.empty
def addCase[T](handler: T => Boolean): Unit = {
actorReceive = actorReceive orElse ({
case msg: T => // call handle at some point, plus some other logic
handler(msg)
})
}
Run Code Online (Sandbox Code Playgroud)
该addCase函数将导致类型擦除警告,这可以通过要求ClassTag如下来解决:def addCase[T: ClassTag](...,但ClassTag仍然无法防止如下调用:
addCase[List[Int]](_ => {println("Int"); true})
addCase[List[String]](_ => {println("String"); false})
actorReceive(List("str")) // will print "Int" …Run Code Online (Sandbox Code Playgroud) 我想为那些没有特定类型类的实例的类型定义一些行为:
// Given
trait SomeTypeclass[T]
// when we have implicit SomeTypeclass[T]
def f[T: SomeTypeclass](x:T):Unit = ???
// when we don't have instance
def f[T !: SomeTypeclass](x: T):Unit = ???
Run Code Online (Sandbox Code Playgroud)
我们可以处理类型类中的差异,但后来我需要创建额外的实例来支持一些通用行为.
有没有办法否定类型绑定?一种使用!:compile编写函数的方法?
(我想在香草Scala中做这个,没有scalaz,没有形状等)
我有一个typeclass Search,Search[A]如果我们有个TypeClass1[A]或一个TypeClass2[A]实例,则有一个实例。优先考虑1实例。
编译如下:
trait TypeClass1[A]
trait TypeClass2[A]
trait Search[A]
object Search extends LPSearch {
implicit def case1[A](implicit ev: TypeClass1[A]): Search[A] = null
}
trait LPSearch {
implicit def case2[A](implicit ev: TypeClass2[A]): Search[A] = null
}
object Test {
implicit val ev1: TypeClass1[Int] = null
implicit val ev2: TypeClass2[Int] = null
implicitly[Search[Int]]
}
Run Code Online (Sandbox Code Playgroud)
就像我期望的那样,隐式搜索finds case1,finds ev1并停止搜索。
但是,如果我们更改TypeClass2为具有更多结构,则隐式搜索将停止工作:
trait TypeClass1[A]
trait TypeClass2[M[_], A]
trait Search[A]
object Search extends LPSearch …Run Code Online (Sandbox Code Playgroud)