Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shapeless: Trying to restrict HList elements by their type

Question 1 - Basic LUBConstraints

My first try playing around with existing LUBConstraints fails for missing evidence (see code block below). Any hint why? Isn't an empty list a valid list of longs? no element violates the constraint.

import shapeless.ops.coproduct
import shapeless.{::, :+:, Coproduct, HNil, HList}

object testLUBConstraints {
  import shapeless.LUBConstraint._

  // !!! see comment on question - this satisfies the implicit below!!! 
  // implicit val hnilLUBForLong = new LUBConstraint[HNil.type, Long] {}

  def acceptLong[L <: HList : <<:[Long]#λ](l: L) = true
  val validLong = acceptLong(1l :: HNil)

  val validEmpty = acceptLong(HNil)
  //  => WHY??? Error: could not find implicit value for evidence parameter of type shapeless.LUBConstraint[shapeless.HNil.type,Long]
  //  MY EXPECTATION WAS: 'implicit def hnilLUB[T] = new LUBConstraint[HNil, T] {}' defined within LUBConstraint companion should provide so

  // val invalid = acceptLong(1.0d :: HNil) -> fails due to missing evidence (as expected)
}

Any help appreciated.

Question 2 - Own Constraint using Coproduct (split into a seperate question: Shapeless: own HList constraint using Coproduct)

Question 3 - restrict case classes by parameter types (split into a separat question: Shapeless: restricting case class types)

like image 750
sthielo Avatar asked Sep 25 '15 09:09

sthielo


People also ask

What is the difference between hlist and hlist in shapeless?

For these reasons, shapeless uses a different generic encoding for product types called heterogeneous listsor HLists4. An HListis either the empty list HNil, or a pair ::[H, T]where His an arbitrary type and Tis another HList.

Why can’t shapeless calculate a genericit?

If shapeless can’t calculate a Genericit means that the type in question isn’t an ADT—somewhere in the algebra there is a type that isn’t a case class or a sealed abstract type. The other potential source of failure is when the compiler can’t calculate a CsvEncoderfor our HList.

What is the power of shapeless?

It allows us to automate migrations between anypair of case classes, in roughly the same amount of code we’d write to handle a singlepair of types using the standard library. Such is the power of shapeless! 6.4Record ops We’ve spent some time in this chapter looking at type classes from the shapeless.ops.hlistand shapeless.ops.coproductpackages.

Does shapeless use tuples and either?

However, instead of using Tuplesand Either, shapeless uses its own data types to represent generic products and coproducts. We’ll introduce these types in the next sections.


1 Answers

The inferred type of the value HNil will be the singleton type HNil.type, which is a proper subtype of HNil. Because type classes like LUBConstraint are invariant, any available instance for HNil won't be found if you're asking for an instance for HNil.type.

There's been some discussion of changing the definition of HNil so that this would work, but it's not trivial, and it's not clear that all the implications of the change are desirable. In the meantime you can write HNil: HNil to upcast the value.

like image 100
Travis Brown Avatar answered Oct 22 '22 12:10

Travis Brown