Shapeless : Checking of the Type Constraints of Polymorphic Functions (lifted types)

Viewed 191

I am writing an internal DSL, and am using Shapeless to enforce type safety. However, I have got stuck with an issue.

The simplified version of the problem is as follows.

Consider the code snippet below:

import shapeless._
import syntax.std.function._
import ops.function._

implicit class Ops[P <: Product, L <: HList](p: P)(implicit val gen: Generic.Aux[P, L]) {
  def ~|>[F, R](f: F)(implicit fp: FnToProduct.Aux[F, L ⇒ R]) =
    f.toProduct(gen.to(p))
}

(1, 2) ~|> ((x: Int, y: Int) ⇒ x + y) // -> at compile time, it ensures the types are aligned.

(1, 2, 3) ~|> ((x: Int, y: Int, z: Int) ⇒ x + y + z) // -> compiles okay

(1, "2", 3) ~|> ((x: Int, y: Int, z: Int) ⇒ x + y + z) // -> gives a compile error, as expected.

However, instead of A, I would like to use a container type Place[A].

case class Place[A](a: A)

val a = Place[Int](1)
val b = Place[Int]("str")

and also ensures the types are aligned with respect to the type parameters.

(a, b) ~|> ((x: Int, y: String) ⇒ x.toString + y)

That is, in the above case, I would like the types to be checked based on the type parameter of Place[_], which in the above case, Int and String respectively.

I highly appreciate your help!

1 Answers
Related