如何从实现类型类的元组中提取类型 [英] How to extract types from a tuple that implements a typeclass
本文介绍了如何从实现类型类的元组中提取类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
函数a可以接收单个参数或元组,这些参数必须是StringIdentifiable类型类的成员
Function a can receive single argument or a tuple, these arguments need to be members of typeclass StringIdentifiable
如何将元组类型提取和分解为也具有typeclass实例的类型
How to extract and decompose tuple type into types that also have instances of the typeclass
@typeclass trait StringIdentifiable[M] {
def identify(id: M): String
}
def a[K: StringIdentifiable] (k:K){
k match{
case (k1) =>
implicitly[StringIdentifiable[K]].identify(k1)
case (k1,k2) =>
implicitly[StringIdentifiable[k1.type]].identify(k1)
implicitly[StringIdentifiable[k2.type]].identify(k2)
}
第二场比赛我出错:
Could not find an instance of StringIdentifiable for k1.type
推荐答案
您可以无形地做到这一点.例如:
You can do this with shapeless. For instance:
import shapeless._, ops.hlist._
object MyPoly extends Poly2 {
implicit def foo[A] = at[A, StringIdentifiable[A]]( (a, f) => f.identify(a) )
}
def a[K: StringIdentifiable, L <: HList, O <: HList](k: K)(
implicit
gen: Generic.Aux[K, L], // decompose K into HList L
lift: LiftAll.Aux[StringIdentifiable, L, O], // find an instance of StringIdentifiable for every element of L
zip: ZipWith[L, O, MyPoly.type] // zip L with its typeclass instances and map the results with the polymorphic function MyPoly
): String :: zip.Out = {
val l = gen.to(k)
val o = lift.instances
implicitly[StringIdentifiable[K]].identify(k) :: zip(l, o)
}
implicit def id1[A,B]: StringIdentifiable[(A, B)] = _ => "1"
implicit val id2: StringIdentifiable[String] = _ => "2"
implicit val id3: StringIdentifiable[Int] = _ => "3"
a(("foo", 42)) // 1 :: 2 :: 3 :: HNil
要完全解决您的问题(IIUC),可能需要使用Shapeless为所有元组自动生成 StringIdentifiable
实例.
A full solution to your problem (IIUC) probably consists of using shapeless to automatically generate StringIdentifiable
instances for all tuples.
trait StringIdentifiable[M] {
def identify(id: M): String
}
object StringIdentifiable {
object MyPoly extends Poly2 {
implicit def foo[A] = at[A, StringIdentifiable[A]]( (a, f) => f.identify(a) )
}
implicit def mkSI[K, L <: HList, O <: HList](
implicit
tup: IsTuple[K],
gen: Generic.Aux[K, L],
lift: LiftAll.Aux[StringIdentifiable, L, O],
zip: ZipWith[L, O, MyPoly.type]
): StringIdentifiable[K] = {
val o = lift.instances
k => {
val l = gen.to(k)
zip(l, o).mkString("(", ", ", ")")
}
}
}
这篇关于如何从实现类型类的元组中提取类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文