问题 在Scala中是否可以在泛型类型τ上指定约束,使得τ


我有一个类型:

class σ

现在我要定义一个类型:

class υ[τ <: σ]

附加要求τ≠σ。

这有可能吗?


9012
2018-05-25 21:00


起源



答案:


使用Miles Sabin的答案 这里 :

trait =!=[A, B]

implicit def neq[A, B] : A =!= B = null
implicit def neqAmbig1[A] : A =!= A = null
implicit def neqAmbig2[A] : A =!= A = null

然后 :

scala> class A
defined class A

scala> class B[C <: A](implicit ev: C =!= A)
defined class B

scala> class D extends A
defined class D

scala> new B[D]()       // OK, D is a subtype of A
res4: B[D] = B@4d8c463c


scala> new B[A]()       // Error, A =:= A
<console>:15: error: ambiguous implicit values:
   both method neqAmbig1 of type [A]=> =!=[A,A]
   and method neqAmbig2 of type [A]=> =!=[A,A]
   match expected type =!=[A,A]

scala> class E
defined class E

scala> new B[E]()       // Error, E is not a subtype of A
<console>:15: error: type arguments [E] do not conform to class B's type parameter bounds [C <: A]

13
2018-05-25 21:14



是A =!= B等于=!= [A,B]?我们可以使用A AnyName B而不是AnyName [A,B]吗? - cloud
@cloud是的, A =!= B 是相同的 =!=[A, B];请注意,这类似于调用方法的两种语法,“operator”语法和“normal”语法。 - Jesper
如果有可能获得比混乱的“模糊隐含值”更好的错误消息,那将是很好的。 - Jesper
@Jesper确实。看到 issues.scala-lang.org/browse/SI-6806 和 github.com/typelevel/scala/pull/32 - Aaron Novstrup


答案:


使用Miles Sabin的答案 这里 :

trait =!=[A, B]

implicit def neq[A, B] : A =!= B = null
implicit def neqAmbig1[A] : A =!= A = null
implicit def neqAmbig2[A] : A =!= A = null

然后 :

scala> class A
defined class A

scala> class B[C <: A](implicit ev: C =!= A)
defined class B

scala> class D extends A
defined class D

scala> new B[D]()       // OK, D is a subtype of A
res4: B[D] = B@4d8c463c


scala> new B[A]()       // Error, A =:= A
<console>:15: error: ambiguous implicit values:
   both method neqAmbig1 of type [A]=> =!=[A,A]
   and method neqAmbig2 of type [A]=> =!=[A,A]
   match expected type =!=[A,A]

scala> class E
defined class E

scala> new B[E]()       // Error, E is not a subtype of A
<console>:15: error: type arguments [E] do not conform to class B's type parameter bounds [C <: A]

13
2018-05-25 21:14



是A =!= B等于=!= [A,B]?我们可以使用A AnyName B而不是AnyName [A,B]吗? - cloud
@cloud是的, A =!= B 是相同的 =!=[A, B];请注意,这类似于调用方法的两种语法,“operator”语法和“normal”语法。 - Jesper
如果有可能获得比混乱的“模糊隐含值”更好的错误消息,那将是很好的。 - Jesper
@Jesper确实。看到 issues.scala-lang.org/browse/SI-6806 和 github.com/typelevel/scala/pull/32 - Aaron Novstrup