Shapeless could not find implicits - scala

I'm trying to generate objects via shapeless
With this code snippet:
import shapeless._
case class T1(i: Int, v: String)
class WorkbenchSpec extends FlatSpec with Matchers {
"Gen tests" should "do smth interesting" in {
println(ObjectGenerators.gen(classOf[T1]))
}
}
object FieldGen extends Poly0 {
implicit val genInt = at[Int](0)
implicit val genString = at[String]("")
}
object ObjectGenerators {
def gen[T, TRepr <: HList](c: Class[T])
(implicit
gen: Generic.Aux[T, TRepr],
fill: ops.hlist.FillWith[FieldGen.type, TRepr]
): T = {
gen.from(HList.fillWith[TRepr](FieldGen))
}
def fillList[T <: HList](implicit fill: ops.hlist.FillWith[FieldGen.type, T]) =
fill()
}
I get an error:
could not find implicit value for parameter fillWith:
shapeless.ops.hlist.FillWith[com.media.gr.core.ObjectGenerators.FieldGen.type,gen.Repr]
gen.from(HList.fillWithgen.Repr)
But in sbt console if I do:
case class T1(i: Int, v: String)
object FieldGen extends Poly0 {
implicit val genInt = at[Int](0)
implicit val genString = at[String]("")
}
def gen[T, TRepr <: HList](c: Class[T])
(implicit
gen: Generic.Aux[T, TRepr],
fill: ops.hlist.FillWith[FieldGen.type, TRepr]
): T = {
gen.from(HList.fillWith[TRepr](FieldGen))
}
I get generated result. What am i doing wrong?

Related

Get case class parameter types as a HList

I'm trying to generate instances of case class using shapeless
This works for generating instances of Foo
case class Foo(x: Int, y: String)
class Context {
val random = new Random()
}
def genInt(context: Context): Int = {
context.random.nextInt()
}
def genString(context: Context): String = {
context.random.nextString(16)
}
object ClassesToGenerators extends Poly1 {
implicit def caseInt = at[Class[Int]](_ => genInt(_))
implicit def caseString = at[Class[String]](_ => genString(_))
}
val gen = Generic[Foo]
val context = new Context()
val classes = classOf[Int] :: classOf[String] :: HNil // can't figure out how to get this hlist programmatically
val generators = classes.map(ClassesToGenerators)
gen.from(generators.zipApply(generators.mapConst(context)))
However, I'm aiming to write something reusable like
def newInstance[T] -> T:
???
which could generate instances of any case classes that takes only int and string parameters.
As mentioned in the code snippet, I'm stuck at getting a hlist of case class attribute types i.e. would like to convert case class Foo(x: Int, y: String) to classOf[Int] :: classOf[String] :: HNil. Any other approaches to this problem are also very appreciated but I'm not looking for a generic way of generating random instances of cases classes (as my use-case is different and used random generator just as an example)
IMHO, Shapeless is better used when you forget about all the fancy stuff and just focus on simple typeclass derivation using HList like this:
import shapeless.{Generic, HList, HNil, :: => :!:}
import scala.util.Random
trait Context {
def random: Random
}
object Context {
object implicits {
implicit final val global: Context = new Context {
override final val random: Random = new Random()
}
}
}
trait Generator[A] {
def generate(context: Context): A
}
object Generator {
final def apply[A](implicit ev: Generator[A]): ev.type = ev
final def generate[A](implicit ev: Generator[A], ctx: Context): A =
ev.generate(ctx)
implicit final val IntGenerator: Generator[Int] =
new Generator[Int] {
override def generate(context: Context): Int =
context.random.nextInt()
}
implicit final val StringGenerator: Generator[String] =
new Generator[String] {
override def generate(context: Context): String =
context.random.nextString(16)
}
implicit final def auto[P <: Product](implicit ev: GeneratorGen[P]): Generator[P] = ev
}
sealed trait GeneratorRepr[R <: HList] extends Generator[R]
object GeneratorRepr {
implicit final val HNilGeneratorRepr: GeneratorRepr[HNil] =
new GeneratorRepr[HNil] {
override def generate(context: Context): HNil =
HNil
}
implicit final def HConsGeneratorRepr[E, T <: HList](
implicit ev: Generator[E], tail: GeneratorRepr[T]
): GeneratorRepr[E :!: T] =
new GeneratorRepr[E :!: T] {
override def generate(context: Context): E :!: T =
ev.generate(context) :: tail.generate(context)
}
}
sealed trait GeneratorGen[P <: Product] extends Generator[P]
object GeneratorGen {
implicit final def instance[P <: Product, R <: HList](
implicit gen: Generic.Aux[P, R], ev: GeneratorRepr[R]
): GeneratorGen[P] = new GeneratorGen[P] {
override def generate(context: Context): P =
gen.from(ev.generate(context))
}
}
Which can be used like this:
import Context.implicits.global
final case class Foo(x: Int, y: String)
val result = Generator.generate[Foo]
// result: Foo = Foo(-2127375055, "鞰Ϗƨ⹼沺㗝䚮Ⴍ욏ꖱꬮӝ闉믃雦峷")
You can see the code running here.
Using built-in Shapeless type classes you can do
import shapeless.ops.hlist.FillWith
import shapeless.{Generic, HList, Poly0}
val context = new Context()
object ClassesToGenerators extends Poly0 {
implicit val caseInt = at[Int](genInt(context))
implicit val caseString = at[String](genString(context))
}
def newInstance[A] = new PartiallyApplied[A]
class PartiallyApplied[A] {
def apply[L <: HList]()(implicit
generic: Generic.Aux[A, L],
fillWith: FillWith[ClassesToGenerators.type, L]
): A = generic.from(fillWith())
}
newInstance[Foo]() // Foo(2018031886,⮐掐禃惌ᰧ佨妞꨸ዤࠒ훿柲籐妭蝱⻤)

Typeclass ops : Enable to find implicit value for parameter

i'm new to typeclass pattern and implicit in scala, below is a code snippet i did to test this pattern, but i don't know why the compareB method is not able to find implicit value for the parameter wrapper , even so i have an implicit field of type IntWrapper[Int] declared.
Does anyone have an idea how implicit are resolved in typeclass ? and why the code below does not compile ?
Thanks
trait IntWrapper[T]{
def test: Boolean
}
trait ProductComparator[T] extends Serializable{
def compare(p1 : T, p2: T): Boolean
}
object ProductComparator{
def apply[A](implicit cmp: ProductComparator[A]) : ProductComparator[A] = cmp
implicit def w: IntWrapper[Int] =
new IntWrapper[Int] {
override def test: Boolean = true
}
implicit def CompareB[T <: Product, Repr <: HList, KRepr <: HList](implicit gen: LabelledGeneric.Aux[T, Repr], keys: Keys.Aux[Repr, KRepr], wrapper: IntWrapper[Int]) : ProductComparator[T] =
new ProductComparator[T] {
override def compare(p1: T, p2: T): Boolean = {
p1.productArity == p2.productArity
}
}
}
case class Emp(a: Int, b: Int)
object Demo extends App{
val comparator = implicitly[ProductComparator[Emp]]
}
Normally implicits for type TC[A] are put either to the companion object of TC or companion object of A.
So transfer
implicit def w: IntWrapper[Int] =
new IntWrapper[Int] {
override def test: Boolean = true
}
from the companion object of ProductComparator to the companion object of IntWrapper
object IntWrapper {
implicit def w: IntWrapper[Int] =
new IntWrapper[Int] {
override def test: Boolean = true
}
}
Then the code should compile.
Alternatively you can import w as #TomerShetah proposed.
Where does Scala look for implicits?
When you define
implicit val foo: Foo = ???
def bar(implicit foo1: Foo) = ???
(in your example foo is w, bar is CompareB, Foo is IntWrapper[Int])
you shouldn't generally assume that foo1 is foo. foo is defined in the current scope and foo1 will be resolved in the scope of bar call site. This can be foo if it's there in a scope or some other implicit.
When doing implicit resolution with type parameters, why does val placement matter?
Setting abstract type based on typeclass
Reverse HList and convert to class?
The issue is scopes. In the line:
val comparator = implicitly[ProductComparator[Emp]]
The method:
def apply[A](implicit cmp: ProductComparator[A]): ProductComparator[A] = cmp
Will be called, where A is Emp. The implicit that can create that, is CompareB. CompareB Needs more implicits. The first 2, comes from imports. So they are in scope. The variable w is defined on the object ProductComparator therefore it is not in the scope where you define val comparator.
In order to add it to scope, you have few options:
Importing it with:
import ProductComparator.w
Moving implicit def w: IntWrapper[Int] to the same scope as trait IntWrapper[T], which makes:
import shapeless.ops.record.Keys
import shapeless.{HList, LabelledGeneric}
trait IntWrapper[T]{
def test: Boolean
}
implicit def w: IntWrapper[Int] =
new IntWrapper[Int] {
override def test: Boolean = true
}
trait ProductComparator[T] extends Serializable{
def compare(p1 : T, p2: T): Boolean
}
object ProductComparator{
def apply[A](implicit cmp: ProductComparator[A]) : ProductComparator[A] = cmp
implicit def CompareB[T <: Product, Repr <: HList, KRepr <: HList](implicit gen: LabelledGeneric.Aux[T, Repr], keys: Keys.Aux[Repr, KRepr], wrapper: IntWrapper[Int]) : ProductComparator[T] =
new ProductComparator[T] {
override def compare(p1: T, p2: T): Boolean = {
p1.productArity == p2.productArity
}
}
}
case class Emp(a: Int, b: Int)
object Demo extends App{
val comparator = implicitly[ProductComparator[Emp]]
}
To read more about where does Scala look for implicits you can read Daniels brilliant post.

Scala implicit specialization

I'm working on a generic conversion library and I'd like to add automatic typeclass derivation using shapeless. It works in the general case but I'd like to introduce Haskellesque newtypes with automatic unwrapping and so I'd like to specialize the deriving function for my NewType type but scalac still picks up the more generic implicit value. Here's the code so far:
import shapeless._, shapeless.syntax._
trait NewType[A] { val value: A }
sealed trait ConversionTree
case class CInt(value: Int) extends ConversionTree
case class CBoolean(value: Boolean) extends ConversionTree
case class CString(value: String) extends ConversionTree
case class CArray(value: List[ConversionTree]) extends ConversionTree
case class CObject(values: Map[String, ConversionTree]) extends ConversionTree
def mergeCObjects(o1: CObject, o2: CObject): CObject = CObject(o1.values ++ o2.values)
trait ConvertsTo[A] {
def convertTo(value: A): ConversionTree
}
object ConvertsTo {
implicit val intConverter = new ConvertsTo[Int] { ... }
implicit val boolConverter = new ConvertsTo[Boolean] { ... }
implicit val stringConverter = new ConvertsTo[String] { ... }
implicit def arrayConverter[A](implicit convertInner: ConvertsTo[A]) = new ConvertsTo[List[A]] { ... }
implicit def objectConverter[A](implicit convertInner: ConvertsTo[A]) = new ConvertsTo[Map[String, A]] { ... }
implicit def newTypeConverter[A](implicit convertInner: ConvertsTo[A]): ConvertsTo[NewType[A]] = new ConvertsTo[NewType[A]] {
override def convertTo(value: NewType[A]): ConversionTree = {
convertInner.convertTo(value.value)
}
}
implicit def deriveHNil: ConvertsTo[HNil] = new ConvertsTo[HNil] {
override def convertTo(value: HNil): ConversionTree = CObject(Map[String, ConversionTree]())
}
// This is the generic case
implicit def deriveHCons[K <: Symbol, V, T <: HList](
implicit
key: Witness.Aux[K],
sv: Lazy[ConvertsTo[V]],
st: Lazy[ConvertsTo[T]]
): ConvertsTo[FieldType[K, V] :: T] = new ConvertsTo[FieldType[K, V] :: T]{
override def convertTo(value: FieldType[K, V] :: T): ConversionTree = {
val head = sv.value.convertTo(value.head)
val tail = st.value.convertTo(value.tail)
mergeCObjects(CObject(Map(key.value.name -> head)), tail.asInstanceOf[CObject])
}
}
// This is the special case for NewTypes
implicit def deriveHConsNewType[K <: Symbol, V, T <: HList](
implicit
key: Witness.Aux[K],
sv: Lazy[ConvertsTo[V]],
st: Lazy[ConvertsTo[T]]
): ConvertsTo[FieldType[K, NewType[V]] :: T] = new ConvertsTo[FieldType[K, NewType[V]] :: T] {
override def convertTo(value: FieldType[K, NewType[V]] :: T): ConversionTree = {
val head = sv.value.convertTo(value.head.value)
val tail = st.value.convertTo(value.tail)
mergeCObjects(CObject(Map(key.value.name -> head)), tail.asInstanceOf[CObject])
}
}
implicit def deriveInstance[F, G](implicit gen: LabelledGeneric.Aux[F, G], sg: Lazy[ConvertsTo[G]]): ConvertsTo[F] = {
new ConvertsTo[F] {
override def convertTo(value: F): ConversionTree = sg.value.convertTo(gen.to(value))
}
}
}
def convertToG[A](value: A)(implicit converter: ConvertsTo[A]): ConversionTree = converter.convertTo(value)
case class Id(value: String) extends NewType[String]
case class User(id: Id, name: String)
println(s"${ConvertsTo.newTypeConverter[String].convertTo(Id("id1"))}")
println(s"User: ${convertToG(User(Id("id1"), "user1"))}")
Output of the first println: CString("id1")
Output of the second println: CObject(Map("id" -> CObject(Map("value" -> CString("id1"))), "name" -> CString("user1")))
I'd like to get rid of the extra CObject around the id field in the second println. As you can see, calling the newTypeConverter directly results in the correct output but it doesn't work when the NewType is embedded in an object(and if I put a breakpoint in the deriveHConsNewType.convertTo method I can verify that it doesn't get called).
I've tried to define deriveHConsNewType like this as well but it didn't help:
implicit def deriveHConsNewType[K <: Symbol, V, N <: NewType[V], T <: HList](
implicit
key: Witness.Aux[K],
sv: Lazy[ConvertsTo[V]],
st: Lazy[ConvertsTo[T]]
): ConvertsTo[FieldType[K, N] :: T] = new ConvertsTo[FieldType[K, N] :: T] { ... }
Can someone explain me how the implicit search works when this kind of overlap occurs and provide a solution to my problem?
EDIT: Solved the issue by making the type variable of ConvertsTo contravariant, scalac now picks the specialized implicit value.
Solved the issue by making the type variable of ConvertsTo contravariant, scalac now picks the specialized implicit value.
trait ConvertsTo[-A] {
def convertTo(value: A): ConversionTree
}

Get the Runtime Type of a Generic Type in Scala

I have the following trait:
trait CSVRowParser[A] {
def parse(row: Seq[String]): Try[A]
}
object CSVRowParser {
implicit def all[A, H <: HList](implicit gen: Generic.Aux[A, H],
read: CSVRowReader[H]): CSVRowParser[A] = new CSVRowParser[A] {
def parse(row: Seq[String]): Try[A] = {
read.from(row).map(gen.from)
}
}
def apply[A](implicit ev: CSVRowParser[A]): CSVRowParser[A] = ev
}
I have another class called CSVReader:
class CSVReader[A: CSVRowParser] {
def parse(path: String): ReaderWithFile[A] = ReaderWithFile[A](path)
case class ReaderWithFile[B: CSVRowParser](path: String) {
...
// how can I here identify the type of B?
}
}
I then do the call like this:
def apply[A: CSVRowParser] = new CSVReader[A]
val reader = apply[Address]
val withCustomConfig: Seq[Address] = reader parse "/csv-parser/address.csv" using CSVParserConfig(Pipe)
How can I get the runtime type of A inside the ReaderWithFile case class?

Provide implicits for all subtypes of sealed type

In my application I have multiple case classes and objects which are part of sealed trait hierarchy. I use them as messages in Akka.
Those classes need to be converted to user friendly form before sending through websocket.
Previously I used big pattern match to convert them in single place, but as number of types grows I would like to use implicit conversion:
object Types {
sealed trait Type
case object SubType1 extends Type
case object SubType2 extends Type
case object SubType3 extends Type
trait Converter[T] {
def convert(t: T): Int
}
}
object Implicits {
import Types._
implicit object Type1Coverter extends Converter[SubType1.type] {
override def convert(t: SubType1.type): Int = 1
}
implicit object Type2Coverter extends Converter[SubType2.type] {
override def convert(t: SubType2.type): Int = 2
}
implicit object Type3Coverter extends Converter[SubType3.type] {
override def convert(t: SubType3.type): Int = 3
}
}
object Conversion {
import Types._
def convert[T: Converter](t: T): Int = {
implicitly[Converter[T]].convert(t)
}
def convert2[T <: Type](t: T)(implicit ev1: Converter[SubType1.type], ev2: Converter[SubType2.type], ev3: Converter[SubType3.type]): Int = {
t match {
case t1#SubType1 =>
implicitly[Converter[SubType1.type]].convert(t1)
case t2#SubType2 =>
implicitly[Converter[SubType2.type]].convert(t2)
case t3#SubType3 =>
implicitly[Converter[SubType3.type]].convert(t3)
}
}
}
I would like to use them as follow:
import Types._
import Conversion._
import Implicits._
val t1 = SubType1
val x1: Int = convert(t1)
val t: Type = SubType2 // T is of type Type
//Is it possible to handle that?
//val x: Int = convert(t)
val y: Int = convert2(t)
I would love to know if there is any "magic" way to generate something like convert2 automatically without writing a macro. Maybe there is already a library which provides macro like this?
Since you have no info at compile time about t's type, you have to work at runtime.
if you put your Converters in a sealed family, you could do something like the follwing, using a technique explained in this question:
import shapeless._
trait AllSingletons[A, C <: Coproduct] {
def values: List[A]
}
object AllSingletons {
implicit def cnilSingletons[A]: AllSingletons[A, CNil] =
new AllSingletons[A, CNil] {
def values = Nil
}
implicit def coproductSingletons[A, H <: A, T <: Coproduct](implicit
tsc: AllSingletons[A, T],
witness: Witness.Aux[H]): AllSingletons[A, H :+: T] =
new AllSingletons[A, H :+: T] {
def values = witness.value :: tsc.values
}
}
trait EnumerableAdt[A] {
def values: Set[A]
}
object EnumerableAdt {
implicit def fromAllSingletons[A, C <: Coproduct](implicit
gen: Generic.Aux[A, C],
singletons: AllSingletons[A, C]): EnumerableAdt[A] =
new EnumerableAdt[A] {
def values = singletons.values.toSet
}
}
object Types {
sealed trait Type
case object SubType1 extends Type
case object SubType2 extends Type
case object SubType3 extends Type
sealed abstract class Converter[T <: Type: ClassTag] {
def convert(t: T): Int
def convertibleObjectClass = implicitly[ClassTag[T]].runtimeClass
}
object Implicits {
implicit object Type1Converter extends Converter[SubType1.type] {
override def convert(t: SubType1.type): Int = 1
}
implicit object Type2Converter extends Converter[SubType2.type] {
override def convert(t: SubType2.type): Int = 2
}
// let's pretend you FORGOT to add Type3Converter
// implicit object Type3Converter extends Converter[SubType3.type] {
// override def convert(t: SubType3.type): Int = 3
// }
}
}
object Conversion {
import Types._
val AllConverters: Map[Class[_], Converter[_ <: Type]] = implicitly[EnumerableAdt[Converter[_ <: Type]]].values
.map(c => c.convertibleObjectClass -> c).toMap
// You're sure you have all the converters here but you can't be sure you remembered to add one per subtype... you have to test it
// you are sure this cast doesn't fail anyway because of how you created the map
def findConverter[T <: Type](t: T) = AllConverters.get(t.getClass).asInstanceOf[Option[Converter[T]]]
def convert2[T <: Type](t: T): Option[Int] = findConverter(t).map(_.convert(t))
}
object Test extends App {
import Types._
import Conversion._
val t: Type = SubType2
val t2: Type = SubType3
// works, because a Converter[Subtype2.type] exists
val a: Option[Int] = convert2(t)
// returns None, because a Converter[Subtype3.type] doesn't exist
val b: Option[Int] = convert2(t2)
}