如何解决无形:在KList上映射自然变换
是否有一种方法可以在KList(例如带有Option ~> Either[String,*]
的{{1}})上映射自然变换(例如HList
)?用KList似乎很自然。
具体地说,我正在尝试执行以下操作:
UnaryTCConstraint
我了解缺少的部分是执行object myNaturalTransformation extends (Option ~> Either[String,*]) {
def apply[T](a: Option[T]): Either[String,T] = a.toRight("oh noe!")
}
def doStuff[KList <: HList: *->*[Option]#λ](klist: KList) = {
klist.map(myNaturalTransformation)
}
所需的Mapper
,Shapeless无法从.map
的案例和myNaturalTransformation
的案例中生成一个。是否有可能获得另一种方式?还是有另一种方法可以映射我正在忽略的KList(除了将UnaryTCConstraint
传递给Mapper
函数之外)?
UnaryTCConstraint
显式生成给定自然变换的映射器。但是,我很好奇是否可以通过Shapeless的def mapper[G[_],HF <: ~>[TC,G]](hf: HF): Mapper[hf.type,L]
实现。
解决方法
UnaryTCConstraint
(*->*
)不是用于映射的,它是一个约束(HList
,Coproduct
,案例类和密封特征是常见的)。对于映射,有类型类NatTRel
,Mapped
,Comapped
,Mapper
等(HList
和Coproduct
分开)。 / p>
尝试约束和类型类
def doStuff[KList <: HList: *->*[Option]#λ,L <: HList](klist: KList)(implicit
natTRel: NatTRel[KList,Option,L,Either[String,*]]
): L = natTRel.map(myNaturalTransformation,klist)
或只键入class
def doStuff[KList <: HList,klist)
或通过L
模式隐藏类型参数PartiallyApplied
def doStuff[KList <: HList] = new PartiallyAppliedDoStuff[KList]
class PartiallyAppliedDoStuff[KList <: HList] {
def apply[L <: HList](klist: KList)(implicit
natTRel: NatTRel[KList,*]]
): L = natTRel.map(myNaturalTransformation,klist)
}
或通过存在性隐藏类型参数L
(但返回类型不精确)
def doStuff[KList <: HList](klist: KList)(implicit
natTRel: NatTRel[KList,_,*]]
) = natTRel.map(myNaturalTransformation,klist)
或使用扩展方法
implicit class NatTRelOps[KList <: HList](val klist: KList) extends AnyVal {
def map[F[_],G[_],L <: HList](f: F ~> G)(implicit
natTRel: NatTRel[KList,F,G]
): L = natTRel.map(f,klist)
}
def doStuff[KList <: HList,*]]
): L = klist.map(myNaturalTransformation)
测试:
doStuff(Option(1) :: Option("a") :: HNil) // compiles
//doStuff(Option(1) :: Option("a") :: true :: HNil) // doesn't compile
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。