简体   繁体   中英

HList foldRight is working, but foldLeft does not compile

This is a follow up on my previous question .

So, I am trying to compute the (kind-of) powerset of an HList of Options. Basically, I want to interpret the HList as a set, in which case the Option value of an element tells me it belongs to the set or not.

I was able to do what I need with the following code:

object combine1 extends Poly2{
    implicit def optionA[A,B <: HList] : Case.Aux[Option[A], List[B], List[Option[A] :: B]] = at{(a, hls) =>
      val x: List[Option[A] :: B] = hls.flatMap{ hl => a match {
          case Some(_) =>
            List(
              None :: hl,
              a :: hl,
            )
          case None =>
            List(None :: hl)
        }
      }
      x
    }

    implicit def someA[A,B <: HList] : Case.Aux[Some[A], List[B], List[Option[A] :: B]] = at{(a, hls) =>
      val x: List[Option[A] :: B] = hls.flatMap{ hl =>
        List(
          None :: hl,
          a :: hl
        )
      }
      x
    }

    implicit val none : Case.Aux[None.type, List[HList], List[HList]] = at{(_, hls) =>
      hls.map(hl => None :: hl)
    }
  }

All this works fine with foldRight :

val h1 = Some(2) :: none[BigDecimal] :: Some("b") :: HNil
h1.foldRight(List(HNil))(combine1).foreach(println)

Prints:

// None :: None :: None :: HNil
// Some(2) :: None :: None :: HNil
// None :: None :: Some(b) :: HNil
// Some(2) :: None :: Some(b) :: HNil

However, foldLeft does not work . Why is that?

h1.foldLeft(List(HNil))(combine1).foreach(println)

Results in the following:

Error:(72, 26) could not find implicit value for parameter folder: shapeless.ops.hlist.LeftFolder[Some[Int] :: Some[Unit] :: Some[String] :: shapeless.HNil,List[shapeless.HNil.type],swaps.tec.util.Experiment.combine1.type]

What am I missing?

NB I know that to use foldLeft I will eventually need to reverse each HList to get the same results as for foldRight , but right now I am only interested in actually left-folding the initial HList . I will fix the out output once I get one :)

FoldLeft takes arguments in a different order. You should define Case.Aux[List[B], Option[A], ...] .

文件夹

折页

https://en.wikipedia.org/wiki/Fold_(higher-order_function)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM