Scala HList manipulation : is a flexible structure possible?

大憨熊 提交于 2019-12-11 01:05:15

问题


I wrote a min example of something I do not manage to do. Am I in the wrong way?

object minNotWoringkExample {

  import shapeless._

  def typed[T](t: => T) {}

  class Bar {
    type L <: HList
  }

  class Foo {
    type UPDATE[L <: HList] <: HList
  }

  class FooI extends Foo {
    type UPDATE[L <: HList] = FilterNot[L, FooI]#Out
  }

  def update[O <: Foo, B <: Bar] = new Bar {
    type L = O#UPDATE[B#L]
  }

  val myBar = new Bar {
    type L = FooI :: Foo :: HNil
  }

  val myUpdatedBar = update[FooI, Bar {type L = FooI :: Foo :: HNil}]

  typed[Bar {type L = Foo :: HNil}](myUpdatedBar)
}

I have an object Bar that holds a HList type. I have an object Foo that has a type that can construct a new HList from a previous HList. In a child class of Foo, FooI, I declare that this Hlist is constructed with, a shapeless FilterNot I create a Bar, update it and when I test the type I obtain the following result :

type mismatch;
 found   : dsl.minWorkExample.Bar{type L = dsl.minWorkExample.FooI#UPDATE[dsl.minWorkExample.Bar{type L = shapeless.::[dsl.minWorkExample.FooI,shapeless.::[dsl.minWorkExample.Foo,shapeless.HNil]]}#L]}
 required: dsl.minWorkExample.Bar{type L = shapeless.::[dsl.minWorkExample.Foo,shapeless.HNil]}
  typed[Bar{type L =  Foo :: HNil}](myUpdatedBar)

Note that it compiles if I had a

FooJ extends Foo {
    type UPDATE[L <: HList] = FooJ :: L
  }

(and the bar objects are instanciated and tested accordingly)

[ADD]

I've tried another version without type declaration and using only value. Seems better structured but not working more. Also shapeless.HList.toString returns a NoSuchMethodException that is still a mystery for me...

object minWorkExample2 extends App {

  import shapeless._

  def typed[T](t: => T) {}

  trait Bar[L <: HList] {
    val l: L

    override def toString = "Bar " + l
  }

  abstract class Foo

  case class FooI() extends Foo

  case class FooII() extends Foo


  abstract class FooParser[L <: HList, F <: Foo](l: L) {
    val up: HList
    type UPDATE = up.type
  }

  case class FooParserA[L <: HList, F <: Foo](l: L)(implicit val remove: Remove[F, L]) extends FooParser[L, F](l) {
    val up = new HListOps[L](l).removeElem[F]._2
  }

  case class FooParserB[L <: HList, F <: Foo](l: L)(implicit val filter: FilterNot[L, F]) extends FooParser[L, F](l) {
    val up = new HListOps[L](l).filterNot[F]
  }

  def update[F <: Foo, L <: HList, FP <: FooParser[L, F]](fp: FP) = new Bar[FP#UPDATE] {
    val l = fp.up
  }


  val myBar = new Bar[FooI :: FooII :: HNil] {
    val l = FooI() :: FooII() :: HNil
  }

  val myUpdatedBar = update[FooI, FooI :: FooII :: HNil, FooParserA[FooI :: FooII :: HNil, FooI]](new FooParserA[FooI :: FooII :: HNil, FooI](myBar.l))
  println(myUpdatedBar.toString)
 //typed[Bar[FooII :: HNil]](myUpdatedBar)
}

来源:https://stackoverflow.com/questions/20006363/scala-hlist-manipulation-is-a-flexible-structure-possible

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!