HList foldLeft,元组为零

编程入门 行业动态 更新时间:2024-10-27 22:29:40
本文介绍了HList foldLeft,元组为零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试使用类型为(HL,Int)的累加器对HList进行 foldLeft ,其中 HL 是HList.下面的程序无法编译.但是,如果我切换到类型为 HL 的简单累加器(只需将注释行与上面的行切换即可),它将编译并起作用.

I'm trying to foldLeft on a HList with an accumulator of type (HL, Int), where HL is a HList. The program below does not compile. However, if I switch to a simpler accumulator of type HL (by just switching the commented lines with the ones above), it compiles and it works.

在一个元组中包装一个HList会打破leftFolder的隐式分辨率.我想念什么?

Wrapping an HList in a tuple breaks the implicit resolution for the leftFolder. What am I missing?

package foo.bar import shapeless.{:+:, ::, CNil, Coproduct, Generic, HList, HNil, Lazy, Poly2} import shapeless.ops.hlist.{LeftFolder, Reverse} object StackOverflow extends App { trait MyTypeclass[T] { def doSomething(t: T): (T, Int) } implicit lazy val stringInstance: MyTypeclass[String] = (t: String) => (t, 0) implicit val hnilInstance: MyTypeclass[HNil] = (t: HNil) => (t, 0) implicit def hlistInstance[H, T <: HList]( implicit head: Lazy[MyTypeclass[H]], tail: MyTypeclass[T] ): MyTypeclass[H :: T] = (ht: H :: T) => ht match { case h :: t => val (hres, hint) = head.value.doSomething(h) val (tres, tint) = tail.doSomething(t) (hres :: tres, hint + tint) } implicit val cnilInstance: MyTypeclass[CNil] = (t: CNil) => ??? implicit def coproductInstance[L, R <: Coproduct]( implicit head: Lazy[MyTypeclass[L]], tail: MyTypeclass[R] ): MyTypeclass[L :+: R] = (lr: L :+: R) => ??? object leftFolder extends Poly2 { implicit def caseAtSimple[F, HL <: HList]: Case.Aux[HL, F, F :: HL] = at { case (acc, f) => f :: acc } implicit def caseAtComplex[F, HL <: HList]: Case.Aux[(HL, Int), F, (F :: HL, Int)] = at { case ((acc, i), f) => (f :: acc, i) } } implicit def genericInstance[T, HL <: HList, LL <: HList]( implicit gen: Generic.Aux[T, HL], myTypeclass: Lazy[MyTypeclass[HL]], // folder: LeftFolder.Aux[HL, HNil, leftFolder.type, LL], folder: LeftFolder.Aux[HL, (HNil, Int), leftFolder.type, (LL, Int)], reverse: Reverse.Aux[LL, HL] ): MyTypeclass[T] = (t: T) => { val generic = gen.to(t) val (transformed, idx) = myTypeclass.value.doSomething(generic) // val ll = transformed.foldLeft(HNil: HNil)(leftFolder) val (ll, _) = transformed.foldLeft((HNil: HNil, 0))(leftFolder) val reversed = reverse(ll) (gen.from(reversed), idx) } def doSomething[T](t: T)(implicit myTypeclass: MyTypeclass[T]): T = myTypeclass.doSomething(t)._1 case class Foo( str1: String, str2: String ) val original = Foo("Hello World!", "Hello there!") val result = doSomething(original) println(result == original) }

推荐答案

您希望隐式函数在单个步骤中完成太多工作.

You want implicits to do too much work in a single step.

尝试再添加一个类型参数 Out

Try to add one more type parameter Out

implicit def genericInstance[T, HL <: HList, Out, LL <: HList]( implicit gen: Generic.Aux[T, HL], myTypeclass: Lazy[MyTypeclass[HL]], //folder: LeftFolder.Aux[HL, (HNil, Int), leftFolder.type, (LL, Int)], folder: LeftFolder.Aux[HL, (HNil, Int), leftFolder.type, Out], ev: Out <:< (LL, Int), // added reverse: Reverse.Aux[LL, HL] ): MyTypeclass[T] = (t: T) => { val generic = gen.to(t) val (transformed, idx) = myTypeclass.value.doSomething(generic) //val (ll, _) = transformed.foldLeft((HNil: HNil, 0))(leftFolder) val (ll, _) = ev(transformed.foldLeft((HNil: HNil, 0))(leftFolder)) val reversed = reverse(ll) (gen.from(reversed), idx) }

了解过度约束的隐式:

books.underscore.io/shapeless-guide/shapeless-guide.html#sec:type-level-programming:chaining (4.3依赖于链接的函数)

books.underscore.io/shapeless-guide/shapeless-guide.html#sec:type-level-programming:chaining (4.3 Chaining dependent functions)

找不到Scala无形状的Generic.Aux隐式参数取消申请

从HList中提取FieldType键和值

如何隐式找出无形HList开头的类型

如何用一元类型构造函数来推断Shapeless记录值的内部类型?

更多推荐

HList foldLeft,元组为零

本文发布于:2023-11-26 19:39:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1634931.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:为零   HList   foldLeft

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!