簡體   English   中英

foldleft HList上的“發散的隱式展開”錯誤

[英]'diverging implicit expansion'-error on foldleft HList

我嘗試進行類型計算以構建集合的某些嵌套結構,但是當我嘗試將類似Map的集合用於List時,我得到了'shapeless.ops.hlist.LeftFolder類型的隱式擴展'錯誤。 T]作為鍵或值類型。 這種嵌套結構的工作原理是:

import shapeless._
import shapeless.ops.hlist._

object poly extends Poly2 {
  implicit def wrapMap[T] = at[T, Int]((end, t) => Map(t -> end))
  //other collection wrap functions
}

def foldToNestedCollections[T <: HList, Out](hl: T)(implicit lf: LeftFolder.Aux[T, Any, poly.type, Out]): Out = lf.apply(hl, 1)

foldToNestedCollections(2 :: HNil) //compiles
foldToNestedCollections(2 :: 3 :: HNil) //compiles

這個結構給出了錯誤:

import shapeless._
import shapeless.ops.hlist._

object poly extends Poly2 {
  implicit def wrapMap[T] = at[T, Int]((end, t) => Map(List(t) -> end)) //or Map(t, List(end)) gives the same error
  //other collection wrap functions
}

def foldToNestedCollections[T <: HList, Out](hl: T)(implicit lf: LeftFolder.Aux[T, Any, poly.type, Out]): Out = lf.apply(hl, 1)

foldToNestedCollections(2 :: HNil) //compiles
foldToNestedCollections(2 :: 3 :: HNil) //does not compile 'diverging ...

更新:如果我構建一個自定義轉換器,它將起作用。 我使用對嵌套Map的早期問題HList的答案來構建此文件。 有什么建議嗎?

import shapeless._
import shapeless.ops.hlist._

sealed trait MyLeftFolder[L <: HList, T] {
  type Out

  def convert(hlist: L, value: T): Out
}

object MyLeftFolder {

  type Aux[L <: HList, T, Out2] = MyLeftFolder[L, T] { type Out = Out2 }

  private trait Impl[L <: HList, T, Out2] extends MyLeftFolder[L, T] {
    override type Out = Out2
  }

  implicit def hnil[T]: Aux[HNil, T, T] = new Impl[HNil, T, T] {
    override def convert(hlist: HNil, value: T): T = value
  }

  implicit def hnil2[T]: Aux[HNil.type, T, T] = new Impl[HNil.type, T, T] {
    override def convert(hlist: HNil.type, value: T): T = value
  }


  implicit def recurseint[L <: HList, T](implicit inner: MyLeftFolder[L, T]): Aux[Int :: L, T, Map[List[Int], inner.Out]] = new Impl[Int :: L, T, Map[List[Int], inner.Out]] {
    override def convert(hlist: Int :: L, value: T): Map[List[Int], inner.Out] = {
      val im = inner.convert(hlist.tail, value)
      Map(List(hlist.head) -> im)
    }
  }
}

def foldToNestedCollections[T <: HList](hl: T)(implicit lf: MyLeftFolder[T, Any]): lf.Out = lf.convert(hl, 1)

foldToNestedCollections(2 :: HNil) //compiles
foldToNestedCollections(2 :: 3 :: HNil) //compiles

使用下面的自定義LeftFolder而不是標准shapeless.ops.hlist.LeftFolder Lazy用法不同。

import shapeless.{::, DepFn2, HList, HNil, Lazy, Poly2}
import shapeless.poly.Case2

trait LeftFolder[L <: HList, In, HF] extends DepFn2[L, In] with Serializable

object LeftFolder {
  def apply[L <: HList, In, F](implicit folder: LeftFolder[L, In, F]): Aux[L, In, F, folder.Out] = folder

  type Aux[L <: HList, In, HF, Out0] = LeftFolder[L, In, HF] { type Out = Out0 }

  implicit def hnilLeftFolder[In, HF]: Aux[HNil, In , HF, In] =
    new LeftFolder[HNil, In, HF] {
      type Out = In
      def apply(l : HNil, in : In): Out = in
    }

  implicit def hlistLeftFolder[H, T <: HList, In, HF, OutH, FtOut]
    (implicit f : Case2.Aux[HF, In, H, OutH], ft : Lazy[LeftFolder.Aux[T, OutH, HF, FtOut]]): Aux[H :: T, In, HF, FtOut] =
    new LeftFolder[H :: T, In, HF] {
      type Out = FtOut
      def apply(l : H :: T, in : In) : Out = ft.value(l.tail, f(in, l.head))
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM