强制类型差异在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.是否有办法强制执行A型和B型应该不同的做法?
3 回答
PIPIONE
TA贡献1829条经验 获得超9个赞
sealed class =!=[A,B]trait LowerPriorityImplicits { implicit def equal[A]: =!=[A, A] = sys.error("should not be called")}object =!= extends LowerPriorityImplicits { implicit def nequal[A,B](implicit same: A =:= B = null): =!=[A,B] = if (same != null) sys.error("should not be called explicitly with same type") else new =!=[A,B]} case class Foo[A,B](a: A, b: B)(implicit e: A =!= B)
// compiles:Foo(1f, 1.0)Foo("", 1.0)Foo("", 1)Foo("Fish", Some("Fish"))// doesn't compile// Foo(1f, 1f)// Foo("", "")
Foo(1, 1)(null)
=!=.nequal(null)
):
sealed class =!=[A,B]trait LowerPriorityImplicits { /** do not call explicitly! */ implicit def equal[A]: =!=[A, A] = sys.error("should not be called")}object =!= extends LowerPriorityImplicits { /** do not call explicitly! */ implicit def nequal[A,B]: =!=[A,B] = new =!=[A,B]}
qq_花开花谢_0
TA贡献1835条经验 获得超7个赞
trait =!=[A, B]implicit def neq[A, B] : A =!= B = null// This pair excludes the A =:= B caseimplicit def neqAmbig1[A] : A =!= A = nullimplicit def neqAmbig2[A] : A =!= A = null
case class Foo[A,B](a : A, b : B)(implicit ev: A =!= B)new Foo(1, "1")new Foo("foo", Some("foo"))// These don't compile// new Foo(1, 1)// new Foo("foo", "foo")// new Foo(Some("foo"), Some("foo"))
更新
type ¬[T] = T => Nothingimplicit def neg[T, U](t : T)(implicit ev : T =!= U) : ¬[U] = nulldef notString[T <% ¬[String]](t : T) = t
scala> val ns1 = notString(1)ns1: Int = 1scala> val ns2 = notString(1.0)ns2: Double = 1.0scala> val ns3 = notString(Some("foo"))ns3: Some[java.lang.String] = Some(foo)scala> val ns4 = notString("foo")<console>:14: error: No implicit view available from java.lang.String => (String) => Nothing. val ns4 = notString2("foo") ^
慕的地10843
TA贡献1785条经验 获得超8个赞
def f[T]( implicit e: T =!= String ) {}
f[String]
<console>:10: error: ambiguous implicit values: both method neqAmbig1 in object =!= of type [A]=> =!=[A,A] and method neqAmbig2 in object =!= of type [A]=> =!=[A,A] match expected type =!=[String,String] f[String] ^
implicitNotFound
@annotation.implicitNotFound(msg = "Cannot prove that ${A} =!= ${B}.")trait =!=[A,B]object =!= { class Impl[A, B] object Impl { implicit def neq[A, B] : A Impl B = null implicit def neqAmbig1[A] : A Impl A = null implicit def neqAmbig2[A] : A Impl A = null } implicit def foo[A,B]( implicit e: A Impl B ): A =!= B = null}
f[String]
:
scala> f[String]<console>:10: error: Cannot prove that String =!= String. f[String] ^
type IsNot[A] = { type λ[B] = A =!= B }
f
def f[T:IsNot[String]#λ] {}
更新A
B
:
@annotation.implicitNotFound(msg = "Cannot prove that ${A} <:!< ${B}.")trait <:!<[A,B]object <:!< { class Impl[A, B] object Impl { implicit def nsub[A, B] : A Impl B = null implicit def nsubAmbig1[A, B>:A] : A Impl B = null implicit def nsubAmbig2[A, B>:A] : A Impl B = null } implicit def foo[A,B]( implicit e: A Impl B ): A <:!< B = null}type IsNotSub[B] = { type λ[A] = A <:!< B }
A
B
:
@annotation.implicitNotFound(msg = "Cannot prove that ${A} <%!< ${B}.")trait <%!<[A,B]object <%!< { class Impl[A, B] object Impl { implicit def nconv[A, B] : A Impl B = null implicit def nconvAmbig1[A<%B, B] : A Impl B = null implicit def nconvAmbig2[A<%B, B] : A Impl B = null } implicit def foo[A,B]( implicit e: A Impl B ): A <%!< B = null}type IsNotView[B] = { type λ[A] = A <%!< B }
- 3 回答
- 0 关注
- 249 浏览
添加回答
举报
0/150
提交
取消