Scala 使用隐式查找;“一”;要注入的HList typeclass的元素
代码如下:Scala 使用隐式查找;“一”;要注入的HList typeclass的元素,scala,shapeless,Scala,Shapeless,代码如下: trait Service[T<: HList] { def doStuff(): Unit } class A class B class C class ServiceAB extends Service[A :: B :: HNil] { override def doStuff(): Unit = println("handling a b") } class ServiceC
trait Service[T<: HList] {
def doStuff(): Unit
}
class A
class B
class C
class ServiceAB extends Service[A :: B :: HNil] {
override def doStuff(): Unit = println("handling a b")
}
class ServiceC extends Service[C :: HNil] {
override def doStuff(): Unit = println("handling c")
}
implicit val serviceAB = new ServiceAB
implicit val serviceC = new ServiceC
def operate[T, W <: HList](x: T)(implicit service: Service[W]) = {
service.doStuff()
}
operate(new C)
trait服务[T我真的不知道你为什么需要这个:)
所以代码可以工作,但如果显式传递类型参数:
operate[C, C :: HNil](new C)
如果您想要相同但隐式的类,可以定义您的类类型:
trait Service[L <: HList, U] { def doStuff(): Unit }
trait lowPriority {
implicit def otherwise[L <: HList, U] =
new Service[L, U] {
def doStuff(): Unit = println("handling otherwise")
}
}
object Service extends lowPriority {
implicit def ab[L <: HList, U]
(implicit e: L =:= (A :: B :: HNil),
s: Selector[L, U]) =
new Service[L, U] {
def doStuff(): Unit = println("handling a b")
}
implicit def c[L <: HList, U]
(implicit e: L =:= (C :: HNil),
s: Selector[L, U]) =
new Service[L, U] {
def doStuff(): Unit = println("handling c")
}
}
}
def operate[T, W <: HList](x: T)(implicit service: Service[W, T]) = {
service.doStuff()
}
有可能使它更通用(因此它将检查您需要的类型是否在HList
,如果不在,则进行三次检查)(使用Curry Howard同构,由Miles Sabin撰写的解释性文章:):
一切正常
operate(new C) //> handling c
operate(new A) //> handling a b
operate(new B) //> handling a b
import reflect.runtime.universe._
type ¬[A] = A => Nothing
type ∨[T, U] = ¬[¬[T] with ¬[U]]
type ¬¬[A] = ¬[¬[A]]
class A
class B
class C
class D //> additional class for example
trait Service[L <: HList, U] { def doStuff(): Unit }
trait lowPriority {
implicit def otherwise[L <: HList, U] =
new Service[L, U] {
def doStuff(): Unit = println("handling otherwise")
}
}
object Service extends lowPriority {
implicit def ab[L <: HList, U]
(implicit e: (¬¬[U] <:< (A ∨ B)),
s: Selector[L, TypeTag[U]]) =
new Service[L, U] {
def doStuff(): Unit = println("handling a b")
}
implicit def c[L <: HList, U](implicit e: U =:= C, s: Selector[L, TypeTag[U]]) =
new Service[L, U] {
def doStuff(): Unit = println("handling c")
}
}
}
def operateBi[T, W <: HList](x: T, w: W)(implicit service: Service[W, T]) = {
service.doStuff()
}
val hl1 = implicitly[TypeTag[A]] :: implicitly[TypeTag[B]] :: HNil
val hl2 = implicitly[TypeTag[C]] :: HNil
operateBi(new C, hl1)
operateBi(new A, hl2)
operateBi(new B, hl1)
operateBi(new D, hl1)