第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

強(qiáng)制類型差異

強(qiáng)制類型差異

強(qiáng)制類型差異在Scala中,我可以在編譯時(shí)強(qiáng)制類型相等。例如: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.是否有辦法強(qiáng)制執(zhí)行A型和B型應(yīng)該不同的做法?
查看完整描述

3 回答

?
揚(yáng)帆大魚

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超9個(gè)贊

借用讓-菲利普的想法,這是有效的:

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("", "")

我可能會(huì)簡(jiǎn)化如下,因?yàn)閷?duì)“作弊”的檢查總是可以避免的。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]}


查看完整回答
反對(duì) 回復(fù) 2019-07-22
?
白板的微信

TA貢獻(xiàn)1883條經(jīng)驗(yàn) 獲得超3個(gè)贊

我有一個(gè)更簡(jiǎn)單的解決方案,它也利用了模糊性,

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"))

更新

我們可以把這個(gè)和我的“神奇的打字技巧”(謝謝@JPP;-)如下:

type ?[T] = T => Nothingimplicit def neg[T, U](t : T)(implicit ev : T =!= U) : ?[U] = nulldef notString[T <% ?[String]](t : T) = t

REPL樣本會(huì)話,

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")
                            ^


查看完整回答
反對(duì) 回復(fù) 2019-07-22
?
慕娘9325324

TA貢獻(xiàn)1783條經(jīng)驗(yàn) 獲得超4個(gè)贊

我喜歡Miles Sabin的第一個(gè)解決方案的簡(jiǎn)單性和有效性,但對(duì)我們得到的錯(cuò)誤沒(méi)有多大幫助這一事實(shí)有點(diǎn)不滿意:

例如,定義如下:

def f[T]( implicit e: T =!= String ) {}

調(diào)度要做f[String]將無(wú)法編譯:

<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]
               ^

我寧愿讓編譯器告訴我“T和字符串沒(méi)有什么不同”,結(jié)果發(fā)現(xiàn),如果添加另一個(gè)層次的派生,那么我們就可以將歧義錯(cuò)誤為隱未發(fā)現(xiàn)錯(cuò)誤。從那時(shí)起,我們可以使用implicitNotFound發(fā)出自定義錯(cuò)誤消息的注釋:

@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}

現(xiàn)在讓我們?cè)囍螂娫?/trans>f[String]:

scala> f[String]<console>:10: error: Cannot prove that String =!= String.
              f[String]
           ^

那好多了。謝謝編譯器。

對(duì)于那些喜歡上下文綁定語(yǔ)法糖的人來(lái)說(shuō),最后一個(gè)技巧是可以定義這個(gè)別名(基于lambdas類型):

type IsNot[A] = { type λ[B] = A =!= B }

然后我們就可以定義f就像這樣:

def f[T:IsNot[String]#λ] {}

它是否容易閱讀是高度主觀的。在任何情況下,都比寫入完整的隱式參數(shù)列表短得多。

更新*為了完整性,這里有一個(gè)等價(jià)的代碼來(lái)表示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 }

并表達(dá)了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 }


查看完整回答
反對(duì) 回復(fù) 2019-07-22
  • 3 回答
  • 0 關(guān)注
  • 605 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)