強制類型差異在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]#λ] {}更新AB:
@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 }AB :
@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 關注
- 289 瀏覽
添加回答
舉報
0/150
提交
取消
