所以我试图在类型可以变化的HList上过滤类型:
import shapeless._
import ops.hlist._, ops.traversable._
object FlexibleTypes {
sealed trait Data {
type H <: HList
def data: H
def ints[Prefix <: HList, Suffix <: HList](
implicit
partitionIntent: Partition.Aux[H, Int, Prefix, Suffix],
prefixToTraversableIntent: ToTraversable.Aux[Prefix, List, Int]
): List[Int] = data.filter[Int].to[List]
def strings[Prefix <: HList, Suffix <: HList](
implicit
partitionIntent: Partition.Aux[H, String, Prefix, Suffix],
prefixToTraversableIntent: ToTraversable.Aux[Prefix, List, String]
): List[String] = data.filter[String].to[List]
}
def Data1[D <: Int :: String :: HNil]( _data: D ) = new Data {
type H = D
val data = _data
}
def Data2[D <: Int :: HNil]( _data: D ) = new Data {
type H = D
val data = _data
}
val datas1 = List(
Data1( 1 :: "a" :: HNil ),
Data1( 2 :: "b" :: HNil )
)
val datas2 = List(
Data1( 1 :: "a" :: HNil ),
Data1( 2 :: "b" :: HNil ),
Data2( 3 :: HNil )
)
val ints1 = datas1.flatMap( _.ints ) // compiles
val ints2 = datas2.flatMap( _.ints ) // does not compile
}
我为ints2
获得的编译错误是:
[error] /Users/caente1/xdotai/xdotai-scala/idris/src/main/scala/flexible.scala:43: could not find implicit value for parameter partitionIntent: shapeless.ops.hlist.Partition.Aux[x$11.H,Int,Prefix,Suffix]
[error] val ints2 = datas2.flatMap( _.ints ) // does not compile
[error] ^
[error] one error found
[error] (idris/compile:compileIncremental) Compilation failed
如果H
是类型参数,也会发生同样的情况。
答案 0 :(得分:2)
所以它似乎必须HList
一直向下:
import shapeless._
import ops.hlist._, ops.traversable._
object FlexibleTypes {
case class Data[H <: HList]( data: H )
def Data1[D <: Int :: String :: HNil]( _data: D ) = Data( _data )
def Data2[D <: Int :: HNil]( _data: D ) = Data( _data )
object ints extends Poly1 {
implicit def toInts[H <: HList, Prefix <: HList, Suffix <: HList](
implicit
partition: Partition.Aux[H, Int, Prefix, Suffix],
prefixToTraversable: ToTraversable.Aux[Prefix, List, Int]
) = at[Data[H]]( _.data.filter[Int].to[List] )
}
val datas =
Data1( 1 :: "a" :: HNil ) ::
Data1( 2 :: "b" :: HNil ) ::
Data2( 3 :: HNil ) ::
HNil
val is: List[Int] = datas.map( ints ).toList.flatten
}