Skip to content

Instantly share code, notes, and snippets.

@yakticus
Last active November 23, 2017 10:04
Show Gist options
  • Select an option

  • Save yakticus/4622facd96ac6bdf17cf to your computer and use it in GitHub Desktop.

Select an option

Save yakticus/4622facd96ac6bdf17cf to your computer and use it in GitHub Desktop.
Hlist filter attempt
import shapeless.HNil
object Example {
trait Fruit
case class Apple()
case class Pear()
// there could be more types of fruit defined elsewhere
class FruitBowl {
private[this] var fruits = HNil
def add[F <: Fruit](fruit: F): Unit = {
fruits = fruit :: fruits // <-- Error:(15, 22) type mismatch;
// found : shapeless.::[F,shapeless.HNil]
// required: shapeless.HNil.type
}
def getAll[F <: Fruit] = fruits.filter[F] // <-- Error:(18, 43) could not find implicit value for parameter partition:
// shapeless.ops.hlist.Partition[shapeless.HNil.type,F]
}
}
@yakticus
Copy link
Copy Markdown
Author

This one works (contributed by @milessabin):

import shapeless._, ops.hlist._
trait Fruit
case class Apple() extends Fruit
case class Pear() extends Fruit

class FruitBowl[L <: HList](val fruits: L) {
  def add[F <: Fruit](fruit: F): FruitBowl[F :: L] = new FruitBowl(fruit :: fruits)

  def getAll[F <: Fruit](implicit pf: Partition[L, F]) = fruits.filter[F]
}

Heres its use on the REPL:

scala> val fb = new FruitBowl(Apple() :: Pear() :: HNil)
fb: FruitBowl[shapeless.::[Apple,shapeless.::[Pear,shapeless.HNil]]] = FruitBowl@6ea082b3

scala> val fb2 = fb.add(Apple())
fb2: FruitBowl[shapeless.::[Apple,shapeless.::[Apple,shapeless.::[Pear,shapeless.HNil]]]] = FruitBowl@60582f8a

scala> val apples = fb2.getAll[Apple]
apples: shapeless.::[Apple,shapeless.::[Apple,shapeless.HNil]] = Apple() :: Apple() :: HNil

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment