I would like to map an Iterator
that contains arbitrarily nested tuples and flatten those.
My search lead me to this Shapeless example
I copied the code:
import shapeless._
import ops.tuple.FlatMapper
import syntax.std.tuple._
trait LowPriorityFlatten extends Poly1 {
implicit def default[T] = at[T](Tuple1(_))
}
object flatten extends LowPriorityFlatten {
implicit def caseTuple[P <: Product](implicit lfm: Lazy[FlatMapper[P, flatten.type]]) =
at[P](lfm.value(_))
}
And the following test works:
def flattenList[P1,P2,P3](l:List[((P1,P2),P3)]): List[(P1,P2,P3)] = {
l.map( flatten(_) )
}
val test1 = List(((1,2),3), ((4,5),6))
val ftest1: List[(Int,Int,Int)] = test1.map( flatten(_) )
println(ftest1.mkString(","))
val ftest1b: List[(Int,Int,Int)] = flattenList(test1)
println(ftest1b.mkString(","))
which compiles and executes as expected. However neither this:
val test2 = List(((1,2),3), ((4,5),6)).toIterator
val ftest2: Iterator[(Int,Int,Int)] = test2.map( flatten(_) )
println(ftest2.mkString(","))
nor this compiles:
val test2 = List(((1,2),3), ((4,5),6)).toIterator
val ftest2: TraversableOnce[(Int,Int,Int)] = test2.map( flatten(_) )
println(ftest2.mkString(","))
with the error:
[error] found : x$6.type (with underlying type ((Int, Int), Int))
[error] required: flatten.ProductCase.Aux[shapeless.HNil,?]
[error] (which expands to) shapeless.poly.Case[flatten.type,shapeless.HNil]{type Result = ?}
[error] val ftest2: TraversableOnce[(Int,Int,Int)] = test2.map( flatten(_) )
This seems to be the result of some interference with the canBuild thingy. Anyone see a
how this should be done correctly?
In addition to this, say I want to define my own iterator so:
def lazyMapP3[P1,P2,P3](i:Iterable[((P1,P2),P3)]) = {
val convertable = new Iterable[(P1,P2,P3)] {
override def iterator: AbstractIterator[(P1,P2,P3)] = {
val converter = new AbstractIterator[(P1,P2,P3)] {
private val iter1 = i.iterator
override def hasNext: Boolean = iter1.hasNext
override def next() = {
val in: ((P1,P2),P3) = iter1.next()
PipeSearch.flatten(in)
}
} // iterator
converter
}
}
convertable
}
The above does not compile due to the same error. But my question is: can I code this
up so that it can accept iterators of any type or arbitrarily nested tuples? If so, what type should
I use for the parameter and return?
TIA