首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Shapeless:在KList上映射自然转换

Shapeless:在KList上映射自然转换
EN

Stack Overflow用户
提问于 2020-10-31 22:34:36
回答 1查看 133关注 0票数 1

有没有办法将自然转换(例如Option ~> Either[String, *])映射到KList (例如带有UnaryTCConstraintHList )上?对于KList来说,这似乎是很自然的事情。

具体地说,我试图做到以下几点:

代码语言:javascript
复制
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)
}

我知道缺少的部分是执行.map所需的Mapper,Shapeless不能从myNaturalTransformation的案例和UnaryTCConstraint生成一个。有没有可能通过其他方式获得一个呢?或者,有没有其他方法可以映射到我忽略的KList上(除了将Mapper传递给doStuff-function之外)?

我能够编写我自己的UnaryTCConstraint版本,其中包含一个

代码语言:javascript
复制
def mapper[G[_], HF <: ~>[TC, G]](hf: HF): Mapper[hf.type, L]

显式地为给定的自然转换生成映射器。然而,我很好奇是否有可能用Shapeless的UnaryTCConstraint实现来做到这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-31 23:51:32

UnaryTCConstraint (*->*)不是用来映射的,它是一个约束(在HListCoproduct、case类和密封特征中很常见)。用于映射的类型类有NatTRelMappedComappedMapper等(分别用于HListCoproduct)。

同时尝试约束类和类型类

代码语言:javascript
复制
def doStuff[KList <: HList: *->*[Option]#λ, L <: HList](klist: KList)(implicit 
  natTRel: NatTRel[KList, Option, L, Either[String, *]]
): L = natTRel.map(myNaturalTransformation, klist)

或者只键入class

代码语言:javascript
复制
def doStuff[KList <: HList, L <: HList](klist: KList)(implicit 
  natTRel: NatTRel[KList, Option, L, Either[String, *]]
): L = natTRel.map(myNaturalTransformation, klist)

或者通过PartiallyApplied模式隐藏类型参数L

代码语言:javascript
复制
def doStuff[KList <: HList] = new PartiallyAppliedDoStuff[KList]

class PartiallyAppliedDoStuff[KList <: HList] {
  def apply[L <: HList](klist: KList)(implicit 
    natTRel: NatTRel[KList, Option, L, Either[String, *]]
  ): L = natTRel.map(myNaturalTransformation, klist)
}

或者通过existential隐藏类型参数L (但返回类型不精确)

代码语言:javascript
复制
def doStuff[KList <: HList](klist: KList)(implicit 
  natTRel: NatTRel[KList, Option, _, Either[String, *]]
) = natTRel.map(myNaturalTransformation, klist)

或者使用扩展方法

代码语言:javascript
复制
implicit class NatTRelOps[KList <: HList](val klist: KList) extends AnyVal {
  def map[F[_], G[_], L <: HList](f: F ~> G)(implicit 
    natTRel: NatTRel[KList, F, L, G]
  ): L = natTRel.map(f, klist)
} 

def doStuff[KList <: HList, L <: HList](klist: KList)(implicit 
  natTRel: NatTRel[KList, Option, L, Either[String, *]]
): L = klist.map(myNaturalTransformation)

测试:

代码语言:javascript
复制
doStuff(Option(1) :: Option("a") :: HNil)           // compiles
//doStuff(Option(1) :: Option("a") :: true :: HNil) // doesn't compile
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64622828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档