LoginSignup
4
2

More than 5 years have passed since last update.

ネストしたTupleで遊ぶ

Last updated at Posted at 2016-01-15

ネストしたタプルをひたすらフラットなタプルにする

きっともっとうまいやり方あるんだろうなー(/ω・\)チラッ

object TupleImplicits {                                                         //defined module TupleImplicits
                                                                                //
  object tuple2Flat {                                                           //
    def apply[A, B, C](x: Tuple2[A, Tuple2[B, C]]) = {                          //
      (x._1, x._2._1, x._2._2)                                                  //
    }                                                                           //
    def apply[A, B, C, D](x: Tuple2[A, Tuple2[B, Tuple2[C, D]]]) = {            //
      (x._1, x._2._1, x._2._2._1, x._2._2._2)                                   //
    }                                                                           //
    def apply[A, B, C, D, E](x: Tuple2[A, Tuple2[B, Tuple2[C, Tuple2[D, E]]]]) =//
      (x._1, x._2._1, x._2._2._1, x._2._2._2._1, x._2._2._2._2)                 //
    }                                                                           //
    def apply[A, B, C, D, E, F](x: Tuple2[A, Tuple2[B, Tuple2[C, Tuple2[D, Tuple//
      (x._1, x._2._1, x._2._2._1, x._2._2._2._1, x._2._2._2._2._1, x._2._2._2._2//
    }                                                                           //
  }                                                                             //
                                                                                //
  object tuple3Flat {                                                           //
    def apply[A, B, C, D](x: Tuple2[A, Tuple3[B, C, D]]) = {                    //
      (x._1, x._2._1, x._2._2, x._2._3)                                         //
    }                                                                           //
  }                                                                             //
                                                                                //
  object tuple4Flat {                                                           //
    def apply[A, B, C, D, E](x: Tuple2[A, Tuple4[B, C, D, E]]) = {              //
      (x._1, x._2._1, x._2._2, x._2._3, x._2._4)                                //
    }                                                                           //
  }                                                                             //
                                                                                //
  implicit class UnTuple[A](t: A) {                                             //
    def shift[B](a: B) = (t, a)                                                 //
    def shift[B, C](a: Tuple2[B, C]) = tuple2Flat(t, a)                         //
    def shift[B, C, D](a: Tuple2[B, Tuple2[C, D]]) = tuple2Flat(t, a)           //
    def shift[B, C, D, E](a: Tuple2[B, Tuple2[C, Tuple2[D, E]]]) = tuple2Flat(t,//
    def shift[B, C, D](a: Tuple3[B, C, D]) = tuple3Flat(t, a)                   //
    def shift[B, C, D, E](a: Tuple4[B, C, D, E]) = tuple4Flat(t, a)             //
  }                                                                             //
}                                                                               //
                                                                                //
import TupleImplicits._                                                         //import TupleImplicits._
                                                                                //
// tuple2 flat                                                                  //
tuple2Flat(1, (2, 3))                                                           //res0: (Int, Int, Int) = (1,2,3)
tuple2Flat(1, (2, (3, 4)))                                                      //res1: (Int, Int, Int, Int) = (1,2,3,4)
tuple2Flat(1, (2, (3, (4, 5))))                                                 //res2: (Int, Int, Int, Int, Int) = (1,2,3,4,5)
                                                                                //
// tuple3 flat                                                                  //
tuple3Flat(1, (2, 3, 4))                                                        //res3: (Int, Int, Int, Int) = (1,2,3,4)
                                                                                //
// tuple4 flat                                                                  //
tuple4Flat(1, (2, 3, 4, 5))                                                     //res4: (Int, Int, Int, Int, Int) = (1,2,3,4,5)
                                                                                //
// shift                                                                        //
1 shift "スフィア"                                                                  //res5: (Int, String) = (1,スフィア)
1 shift ("スフィア", "乃木坂46")                                                       //res6: (Int, String, String) = (1,スフィア,乃木坂46)
(1 shift ("バナナマン" shift (3.0 shift 4L)))                                        //res7: (Int, String, Double, Long) = (1,バナナマン,3.0,4)
                                                                                //
                                                                   //

で、

なにがしたかったんだったか忘れた

shapless

コメントで頂いたのを使ってみた

import shapeless._                                                              //import shapeless._
import ops.tuple.FlatMapper                                                     //import shapeless.ops.tuple.FlatMapper
import syntax.std.tuple._                                                       //import shapeless.syntax.std.tuple._
import test._                                                                   //import shapeless.test._
                                                                                //
trait LowPriorityFlatten extends Poly1 {                                        //defined trait LowPriorityFlatten
  implicit def default[T] = at[T](Tuple1(_))                                    //
}                                                                               //
object flatten extends LowPriorityFlatten {                                     //defined module flatten
  implicit def caseTuple[P <: Product](implicit fm: FlatMapper[P, flatten.type])//
    at[P](_.flatMap(flatten))                                                   //
}                                                                               //
                                                                                //
val t1 = (1, ((2, 3), 4))                                                       //t1: (Int, ((Int, Int), Int)) = (1,((2,3),4))
val f1 = flatten(t1)                                                            //f1: (Int, Int, Int, Int) = (1,2,3,4)
val t2 = (1, (2, (3, 4)))                                                       //t2: (Int, (Int, (Int, Int))) = (1,(2,(3,4)))
flatten(t2)                                                                     //res0: (Int, Int, Int, Int) = (1,2,3,4)
val t3 = ((1, 2), 3)                                                            //t3: ((Int, Int), Int) = ((1,2),3)
flatten(t3)                                                                     //res1: (Int, Int, Int) = (1,2,3)
val t4 = (((((5, (4, (1, 2))), 3))))                                            //t4: ((Int, (Int, (Int, Int))), Int) = ((5,(4,(1,2))),3)
val f4 = flatten(t4)                                                            //f4: (Int, Int, Int, Int, Int) = (5,4,1,2,3)
                                                                                //
f4.getClass                                                                     //res2: Class[?0] = class scala.Tuple5
                                                                                //

すげぇ・・・

4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2