복붙노트

[SCALA] 추가하거나 스칼라에서 튜플에 요소를 앞에 추가하는 방법

SCALA

추가하거나 스칼라에서 튜플에 요소를 앞에 추가하는 방법

나는 튜플을 입력 안전을 잃지 않고 요소를 추가 할 수 있습니다. 이것은 내가 달성하고자하는 것입니다 :

val tuple = ("", 1, 1f) // (String, Int, Float)

val newTuple:(String, Int, Float, Double) = tuple :+ 1d

해결법

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

    1.그것은 당신이 또한 몇 줄이에 대한 코드 생성기를 쓸 수 있는지 주목할 필요가 :

    그것은 당신이 또한 몇 줄이에 대한 코드 생성기를 쓸 수 있는지 주목할 필요가 :

    val tupadd = for (n <- 2 to 20) yield {
      val t = (0 until n).map(i => ('A'+i).toChar).mkString(", ")
      val u = ('A'+n).toChar
      val i = (0 until n).map(i => "x._"+(i+1)).mkString(", ")
      List(
        s"implicit class TupOps$n[$t](val x: ($t)) extends AnyVal {",
        s"  def :+[$u](y: $u) = ($i, y)",
        s"  def +:[$u](y: $u) = (y, $i)",
        "}"
      ).mkString("\n")
    }
    

    이러한 아웃 인쇄, 엠 파일에 '스틱, 그리고 넌 좋은 이동합니다 :

    scala> implicit class TupOps2[A, B](val x: (A, B)) extends AnyVal {
         |   def :+[C](y: C) = (x._1, x._2, y)
         |   def +:[C](y: C) = (y, x._1, x._2)
         | }
    defined class TupOps2
    
    scala> (1,"salmon") :+ true
    res15: (Int, String, Boolean) = (1,salmon,true)
    
  2. ==============================

    2.볼품은 지금 트릭을 수행합니다. 첨가

    볼품은 지금 트릭을 수행합니다. 첨가

    import shapeless.syntax.std.tuple._
    

    코드가 바로 컴파일하기 전에.

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

    3.나는 멋진 볼품 라이브러리의 도움으로 해결책을 발견하고는 HList입니다

    나는 멋진 볼품 라이브러리의 도움으로 해결책을 발견하고는 HList입니다

    /*
      Define an implicit class to add the methods
      It accepts any tuple as we have typed it as Product
    */
    implicit class TupleOps[A <: Product](t: A) {
    
      /*
        Declare the method to append
    
        B - The type of element we want to append
        L - The HList representing the tuple A
        P - The HList after appending B
        R - The final result
      */
      def :+[B, L <: HList, P <: HList, R <: Product](b: B)(
        /*
          We need some tools to help with the conversion
    
          hlister - Converts a tuple into an HList
          prepend - Can prepend one HList before another
          tupler  - Can convert an HList into a tuple
        */
        implicit hlister: HListerAux[A, L], prepend: PrependAux[L, B :: HNil, P], tupler: TuplerAux[P, R]):R =
          // Let the helpers do their job
          tupler(prepend(hlister(t), b :: HNil))
    
      /*
        The prepend method is similar to the append method but does not require
        the extra effort to append
      */
      def +:[B, L <: HList, R <: Product](b: B)(
        // Here we use the :: type of shapeless
        implicit hlister: HListerAux[A, L], tupler: TuplerAux[B :: L, R]):R =
          tupler(b :: hlister(t))
    }
    
    // usage is like this
    ("", 1, 1f) :+ 1d  //> res0: (String, Int, Float, Double) = ("",1,1.0,1.0)
    1d +: ("", 1, 1f)  //> res1: (Double, String, Int, Float) = (1.0,"",1,1.0)
    

    당신이 암시 적 변환을 처리해야하는 경우,이 솔루션은 케이스 클래스와 함께 작동하지 않습니다. 나는 지금 (렉스 커의 코드를 기반으로) 다음 구현에 복귀

    def char(n: Int) = ('A' + n).toChar
    def prop(n: Int) = "t._" + (n + 1)
    
    val result =
      for (n <- 1 to 21) yield {
    
        val range = (0 until n)
        val tupleTypeParams = range map char mkString ", "
        val tupleProperties = range map prop mkString ", "
    
        val elementType = char(n)
        val elementProperty = prop(n)
    
        val first = n == 1
        val tupleType = if (first) s"Tuple1[$tupleTypeParams]" else s"($tupleTypeParams)"
        val tupleInstance = if (first) s"Tuple1($tupleProperties)" else s"($tupleProperties)"
    
        val resultType = s"($tupleTypeParams, $elementType)"
    
        s"""|implicit def tupleOps$n[$tupleTypeParams, $elementType] = 
            |  new TupleAppendOps[$tupleType, $elementType, $resultType] {
            |    def append(t: $tupleType, e: $elementType) = ($tupleProperties, e)
            |    def init(t: $resultType) = $tupleInstance
            |    def last(t: $resultType) = $elementProperty
            |  }""".stripMargin
      }
    
    println(result mkString "\n")
    
  4. ==============================

    4.당신은 정확히 예를 수행 https://github.com/leonardschneider/macrogen에서 매크로 낙원 스칼라 지점에 따라 내 실험 매크로 라이브러리를 시도 할 수 있습니다.

    당신은 정확히 예를 수행 https://github.com/leonardschneider/macrogen에서 매크로 낙원 스칼라 지점에 따라 내 실험 매크로 라이브러리를 시도 할 수 있습니다.

    내가 전화를 체인 수없는 경우, 비록 지금은 아직 몇 가지 버그가 있습니다.

  5. from https://stackoverflow.com/questions/15349439/how-to-append-or-prepend-an-element-to-a-tuple-in-scala by cc-by-sa and MIT license