복붙노트

[SCALA] 어떻게 스칼라에서 implicits 체인 수 있습니까?

SCALA

어떻게 스칼라에서 implicits 체인 수 있습니까?

포주 - 내 - 라이브러리 패턴은 나에게 보이는 방법을 구현하는 하나에 그 클래스에서 암시 적 변환을 사용할 수 있도록하여 클래스에 메서드를 추가 할 수 있습니다.

이 제한 주위에 방법이 있나요 B와 C에 대한 또 다른 암시 B에 암시 적 사용 a 스칼라는이 같은 암시 적 변환은 그러나 일어나고 허용하지 않는, 그래서 나는 C A에서 가지고 수없는 이유는 무엇입니까?

해결법

  1. ==============================

    1.스칼라는 방법을 찾기 위해 노력하고 하나 이상의 변환을 적용하지 않을 수있는 방법을 추가 할 수있는 자동 변환에 대한 제한이 있습니다. 예를 들면 :

    스칼라는 방법을 찾기 위해 노력하고 하나 이상의 변환을 적용하지 않을 수있는 방법을 추가 할 수있는 자동 변환에 대한 제한이 있습니다. 예를 들면 :

    class A(val n: Int)
    class B(val m: Int, val n: Int)
    class C(val m: Int, val n: Int, val o: Int) {
      def total = m + n + o
    }
    
    // This demonstrates implicit conversion chaining restrictions
    object T1 { // to make it easy to test on REPL
      implicit def toA(n: Int): A = new A(n)
      implicit def aToB(a: A): B = new B(a.n, a.n)
      implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n)
    
      // won't work
      println(5.total)
      println(new A(5).total)
    
      // works
      println(new B(5, 5).total)
      println(new C(5, 5, 10).total)
    }
    

    편집 :보기 경계 ( '<%') 스칼라 2.11 https://issues.scala-lang.org/browse/SI-7629을하기 때문에 사용되지 않습니다 (당신은 대신 타입의 클래스를 사용할 수 있습니다)

    암시 적 정의가 암시 적 매개 변수 자체 (행보기)를 필요로하는 경우에는, 스칼라는 필요한만큼의 추가 암시 적 값을 찾을 것입니다. 마지막 예에서 계속 :

    // def m[A <% B](m: A) is the same thing as
    // def m[A](m: A)(implicit ev: A => B)
    
    object T2 {
      implicit def toA(n: Int): A = new A(n)
      implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
      implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)
    
      // works
      println(5.total)
      println(new A(5).total)
      println(new B(5, 5).total)
      println(new C(5, 5, 10).total)
    }
    

    "매직!", 당신은 말할지도 모른다. 별로. 여기에 컴파일러가 각각 번역 할 방법입니다

    object T1Translated {
      implicit def toA(n: Int): A = new A(n)
      implicit def aToB(a: A): B = new B(a.n, a.n)
      implicit def bToC(b: B): C = new C(b.m, b.n, b.m + b.n)
    
      // Scala won't do this
      println(bToC(aToB(toA(5))).total)
      println(bToC(aToB(new A(5))).total)
    
      // Just this
      println(bToC(new B(5, 5)).total)
    
      // No implicits required
      println(new C(5, 5, 10).total)
    }
    
    object T2Translated {
      implicit def toA(n: Int): A = new A(n)
      implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
      implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)
    
      // Scala does this
      println(bToC(5)(x => aToB(x)(y => toA(y))).total)
      println(bToC(new A(5))(x => aToB(x)(identity)).total)      
      println(bToC(new B(5, 5))(identity).total)
    
      // no implicits required
      println(new C(5, 5, 10).total)
    }
    

    bToC가 암시 적 변환으로 사용하는 동안 그래서, ATOB 및 TOA 대신 암시 적 변환으로 체인 연결되는 암시 적 매개 변수로 전달되고있다.

    편집하다

    관심의 관련 질문 :

  2. ==============================

    2.당신도, 암시 적 매개 변수를 사용하여 원을 구축 할 수 있습니다. 이것에 의해 나타나는 바와 같이 그 그러나, 컴파일러에 의해 검출된다 :

    당신도, 암시 적 매개 변수를 사용하여 원을 구축 할 수 있습니다. 이것에 의해 나타나는 바와 같이 그 그러나, 컴파일러에 의해 검출된다 :

    class Wrap {
      class A(implicit b : B)
      class B(implicit c : C)
      class C(implicit a : A)
    
      implicit def c = new C
      implicit def b = new B
      implicit def a = new A
    }
    

    사용자에게 주어진 오류 (들)가 있지만, 수만큼 명확하지 않다; 그것은 단지 세 건설 현장에 대한 매개 변수에 대한 암시 적 가치를 찾을 수 없습니다 뿌려줍니다. 즉 덜 명백한 경우에 근본적인 문제를 모호 할 수도 있습니다.

  3. ==============================

    3.여기에 또한 경로를 축적 코드입니다.

    여기에 또한 경로를 축적 코드입니다.

    import scala.language.implicitConversions
    
    // Vertices
    case class A(l: List[Char])
    case class B(l: List[Char])
    case class C(l: List[Char])
    case class D(l: List[Char])
    case class E(l: List[Char])
    
    // Edges
    implicit def ad[A1 <% A](x: A1) = D(x.l :+ 'A')
    implicit def bc[B1 <% B](x: B1) = C(x.l :+ 'B')
    implicit def ce[C1 <% C](x: C1) = E(x.l :+ 'C')
    implicit def ea[E1 <% E](x: E1) = A(x.l :+ 'E')
    
    def pathFrom(end:D) = end
    
    pathFrom(B(Nil))   // res0: D = D(List(B, C, E, A))
    
  4. from https://stackoverflow.com/questions/5332801/how-can-i-chain-implicits-in-scala by cc-by-sa and MIT license