How is it possible that type parameter in call to get[A] is Nothing in this snippet? What can I do to force a compiler to produce an error when get is called without explicit type parameter?
case class User(email: String)
object Hello {
def main(args: Array[String]): Unit = {
val store = new ObjectStore
store.get
}
}
class ObjectStore {
def get[A: Manifest]: Option[A] = {
println(manifest[A].toString())
None
}
}
Based on this blog post, the following should work:
#implicitNotFound("Nothing was inferred")
sealed trait NotNothing[-T]
object NotNothing {
implicit object notNothing extends NotNothing[Any]
implicit object `\n The error is because the type parameter was resolved to Nothing` extends NotNothing[Nothing]
}
class ObjectStore {
def get[T](implicit evManifest: Manifest[T], evNotNothing: NotNothing[T]): Option[T] = {
println(manifest[T].toString())
None
}
}
object X {
val oo = new ObjectStore().get[Any]
//fails to compile
//val o = new ObjectStore().get
}
Related
(Scala 2.11.8)
Consider the following code:
object ScalaTest extends App {
class Wrapper {
import Wrapper._
def init(): Unit = {
// "could not find implicit value for parameter tc: ScalaTest.Wrapper.TC[Int]"
printWithTC(123)
// Compiles
printWithTC(123)(IntTC)
// Compiles again!
printWithTC(132)
}
}
object Wrapper {
trait TC[A] {
def text(a: A): String
}
implicit object IntTC extends TC[Int] {
override def text(a: Int) = s"int($a)"
}
def printWithTC[A](a: A)(implicit tc: TC[A]): Unit = {
println(tc.text(a))
}
}
(new Wrapper).init()
}
I have a bunch of questions regarding this piece of code:
Why doesn't IntTC get resolved in the first place?
Why it compiles after being used once? (if you comment out the first invocation, code works)
Where should typeclass implicits be placed to get resolved properly?
Use a val with a explicit return type. See https://github.com/scala/bug/issues/801 and https://github.com/scala/bug/issues/8697 (among others).
Implicit objects have the same issue as implicit vals and defs with inferred return types. As for your second question: when IntTC is used explicitly you force the compiler to typecheck it, so after that point its type is known and can be found by implicit search.
class Wrapper {
import Wrapper._
def init(): Unit = {
// Compiles
printWithTC(123)
// Compiles
printWithTC(123)(IntTC)
// Compiles
printWithTC(132)
}
}
object Wrapper {
trait TC[A] {
def text(a: A): String
}
implicit val IntTC: TC[Int] = new TC[Int] {
override def text(a: Int) = s"int($a)"
}
def printWithTC[A](a: A)(implicit tc: TC[A]): Unit = {
println(tc.text(a))
}
}
If you really want your implicit to be evaluated lazily like an object, you can use an implicit lazy val with an explicit type.
Define the implicit before the use of it.
object Wrapper {
trait TC[A] {
def text(a: A): String
}
implicit object IntTC extends TC[Int] {
override def text(a: Int) = s"int($a)"
}
def printWithTC[A](a: A)(implicit tc: TC[A]): Unit = {
println(tc.text(a))
}
}
class Wrapper {
import Wrapper._
def init(): Unit = {
// "could not find implicit value for parameter tc: ScalaTest.Wrapper.TC[Int]"
printWithTC(123)
// Compiles
printWithTC(123)(IntTC)
// Compiles again!
printWithTC(132)
}
}
(new Wrapper).init()
I have written automatic type class derivation in order to automatically generate elasticsearch Json mapping for case classes.
For that I am using the TypeClass type class in shapeless.
The problem I have is that many fields in the case classes we use are Scala enumerations.
For example
object ConnectionState extends Enumeration {
type ConnectionState = Value
val ordering, requested, pending, available, down, deleting, deleted, rejected = Value
}
Or
object ProductCodeType extends Enumeration {
type ProductCodeType = Value
val devpay, marketplace = Value
}
It seems I have to define a specific implicit instance for every Enumeration that is defined in order that the automatic derivation will pick it up (e.g. for both ConnectionState and ProductCodeType).
I cannot have one implicit def for Enumeration such as
implicit def enumerationMapping: MappingEncoder[Enumeration] = new MappingEncoder[Enumeration] {
def toMapping = jSingleObject("type", jString("text"))
}
that will work for all enumeration types.
I tried making the type class covariant, and a bunch of other things but nothing helped.
Any ideas?
Here is the derivation code:
object Mapping {
trait MappingEncoder[T] {
def toMapping: Json
}
object MappingEncoder extends LabelledProductTypeClassCompanion[MappingEncoder] {
implicit val stringMapping: MappingEncoder[String] = new MappingEncoder[String] {
def toMapping = jSingleObject("type", jString("text"))
}
implicit val intMapping: MappingEncoder[Int] = new MappingEncoder[Int] {
def toMapping = jSingleObject("type", jString("integer"))
}
implicit def seqMapping[T: MappingEncoder]: MappingEncoder[Seq[T]] = new MappingEncoder[Seq[T]] {
def toMapping = implicitly[MappingEncoder[T]].toMapping
}
implicit def optionMapping[T: MappingEncoder]: MappingEncoder[Option[T]] = new MappingEncoder[Option[T]] {
def toMapping = implicitly[MappingEncoder[T]].toMapping
}
object typeClass extends LabelledProductTypeClass[MappingEncoder] {
def emptyProduct = new MappingEncoder[HNil] {
def toMapping = jEmptyObject
}
def product[F, T <: HList](name: String, sh: MappingEncoder[F], st: MappingEncoder[T]) = new MappingEncoder[F :: T] {
def toMapping = {
val head = sh.toMapping
val tail = st.toMapping
(name := head) ->: tail
}
}
def project[F, G](instance: => MappingEncoder[G], to: F => G, from: G => F) = new MappingEncoder[F] {
def toMapping = jSingleObject("properties", instance.toMapping)
}
}
}
}
I was able to fix the problem by adding additional implicit defs to scope:
implicit def enumerationMapping[T <: Enumeration#Value]: MappingEncoder[T] = new MappingEncoder[T] {
def toMapping = jSingleObject("type", jString("text"))
}
implicit def enumerationSeqMapping[T <: Enumeration#Value]: MappingEncoder[Seq[T]] = new MappingEncoder[Seq[T]] {
def toMapping = jSingleObject("type", jString("text"))
}
The second implicit was needed as some of the case classes had members of type Seq[T] where T is some enumeration type.
trait Encoder[From, To] {
def encode(x: From): To
}
object Encoder {
implicit val thingToString: Encoder[Thing, String] = new Encoder[Thing, String] {
def encode(x: Thing): String = x.toString
}
}
trait Config {
type Repr
}
class MyConfig extends Config { type Repr = String }
//class ConcreteConfig { type Repr = String }
class Api[T](val config: Config) {
def doSomething(value: T)(implicit encoder: Encoder[T, config.Repr]): Unit = {}
}
case class Thing(a: Int)
object Test extends App {
import Encoder._
val api = new Api[Thing](new MyConfig)
api.doSomething(Thing(42))
}
The call to api.doSomething fails to compile:
could not find implicit value for parameter encoder: Encoder[Thing,Test.api.config.Repr]
If I change the signature of class Api[T]'s constructor so that it takes a ConcreteConfig, then the compiler can tell that config.Repr == String and the implicit lookup succeeds. But this wouldn't really work for my use case.
Is there any other way to guide the implicit lookup? Am I losing type info because I'm missing a type refinement or something?
This can't be achieved since config.Repr is not a stable path. The compiler can't determine that config.Repr = String, even though the runtime value of config is of type MyConfig.
This is going to work only if you can provide concrete config instance as a type parameter in Api, which will tell compiler what is the exact type of Repr:
class Api[T, C <: Config](val config: C) {
def doSomething(value: T)(implicit encoder: Encoder[T, config.Repr]): Unit = {}
}
object Test extends App {
import Encoder._
val api = new Api[Thing, MyConfig](new MyConfig)
api.doSomething(Thing(42))
}
Infer types one step at a time. Also, I don't see any reason for using value-dependent types here (or, for that matter, anywhere; that's a different question though).
trait Encoder[From, To] {
def encode(x: From): To
}
object Encoder {
implicit val thingToString: Encoder[Thing, String] = new Encoder[Thing, String] {
def encode(x: Thing): String = x.toString
}
}
trait Config {
type Repr
}
class MyConfig extends Config { type Repr = String }
// class ConcreteConfig { type Repr = String }
case class Api[T, C <: Config](val config: C) {
def doSomething(value: T)(implicit encoder: Encoder[T, C#Repr]): Unit = ()
}
case class ApiFor[T]() {
def withConfig[C <: Config](config: C): Api[T,C] = Api(config)
}
case class Thing(a: Int)
object Test extends App {
import Encoder._
val api = ApiFor[Thing] withConfig new MyConfig
// compiles!
api.doSomething(Thing(42))
}
I am trying to create a type class in Scala and use it to make a simple polymorphic case class. This example doesn't compile and gives "could not find implicit value for parameter writer:A$A228.this.ValueWriter[T]". I can't really figure out what could be going wrong or where to start.
trait Keeper
case class StringKeeper(measure: String) extends Keeper
case class StringLengthKeeper(measure: Int) extends Keeper
trait ValueWriter[A] {
def write(value: String): A
}
object DefaultValueWriters {
implicit val stringWriter = new ValueWriter[StringKeeper] {
def write(value: String) = StringKeeper(value)
}
implicit val stringLengthWriter = new ValueWriter[StringLengthKeeper] {
def write(value: String) = StringLengthKeeper(value.length)
}
}
object Write {
def toWrite[A](value: String)(implicit writer: ValueWriter[A]) = {
writer.write(value)
}
}
case class WriterOfKeepers[T <: Keeper](value: String) {
def run: T = {
Write.toWrite[T](value)
}
}
import DefaultValueWriters._
val writerLengthKeeper = WriterOfKeepers[StringLengthKeeper]("TestString")
writerLengthKeeper.run
There is no implicit ValueWriter in scope when you call Write.toWrite.
You need to have the implicit parameter in the constructor
case class WriterOfKeepers[T <: Keeper : ValueWriter](value: String) {
def run: T = {
Write.toWrite[T](value)
}
}
or in the method
case class WriterOfKeepers[T <: Keeper](value: String) {
def run(implicit writer: ValueWriter[T]): T = {
Write.toWrite(value)
}
}
or find some other way compatible with your requirements (and I don't know those).
I'm trying to add an implicit value to (what I believe is) the companion object of a case class, but this implicit value is not found.
I'm trying to achieve something like the following:
package mypackage
object Main {
def main(args: Array[String]): Unit = {
val caseClassInstance = MyCaseClass("string")
val out: DataOutput = ...
serialize(out, caseClassInstance)
// the above line makes the compiler complain that there is no
// Serializer[MyCaseClass] in scope
}
def serialize[T : Serializer](out: DataOutput, t: T): Unit = {
...
}
}
object MyCaseClass {
// implicits aren't found here
implicit val serializer: Serializer[MyCaseClase] = ...
}
case class MyCaseClass(s: String) {
// some other methods
}
I've explicitly added the package here to show that both the MyCaseClass case class and object should be in scope. I know that the object is actually being constructed because I can get this to compile if I add
implicit val serializer = MyCaseClass.serializer
to main (though notably not if I add import MyCaseClass.serializer).
I'm concerned that the MyCaseClass object is not actually a companion of the case class, because if I explicitly define apply and unapply on the object and then attempt to call MyCaseClass.apply("string") in main, the compiler gives the following error:
ambiguous reference to overloaded definition,
both method apply in object MyCaseClass of type (s: String)mypackage.MyCaseClass
and method apply in object MyCaseClass of type (s: String)mypackage.MyCaseClass
match argument types (String)
val a = InputRecord.apply("string")
^
If it's not possible to take this approach, is there a way to use type classes with case classes without creating an implicit value every time it must be brought into scope?
EDIT: I'm using scala 2.10.3.
EDIT 2: Here's the example fleshed out:
package mypackage
import java.io.{DataOutput, DataOutputStream}
object Main {
def main(args: Array[String]): Unit = {
val caseClassInstance = MyCaseClass("string")
val out: DataOutput = new DataOutputStream(System.out)
serialize(out, caseClassInstance)
// the above line makes the compiler complain that there is no
// Serializer[MyCaseClass] in scope
}
def serialize[T : Serializer](out: DataOutput, t: T): Unit = {
implicitly[Serializer[T]].write(out, t)
}
}
object MyCaseClass {
// implicits aren't found here
implicit val serializer: Serializer[MyCaseClass] = new Serializer[MyCaseClass] {
override def write(out: DataOutput, t: MyCaseClass): Unit = {
out.writeUTF(t.s)
}
}
}
case class MyCaseClass(s: String) {
// some other methods
}
trait Serializer[T] {
def write(out: DataOutput, t: T): Unit
}
This actually compiles, though. I am getting this issue when using Scoobi's WireFormat[T] instead of Serializer, but can't provide a concise, runnable example due to complexity and the Scoobi dependency. I will try to create a more relevant example, but it seems as though the issue is not as general as I thought.
It turns out that the type class instances actually need to be implicit values, rather than objects. The MyCaseClass object above works because its serializer is assigned to an implicit value. However, this implementation
object MyCaseClass {
implicit object MyCaseClassSerializer extends Serializer[MyCaseClass] {
override def write(out: DataOutput, t: MyCaseClass): Unit = {
out.writeUTF(t.s)
}
}
}
fails with the error
Main.scala:9: error: could not find implicit value for evidence parameter of type mypackage.Serializer[mypackage.MyCaseClass]
serialize(out, caseClassInstance)
^
In my real code, I was using an auxiliary function to generate the Serializer[T] (see https://github.com/NICTA/scoobi/blob/24f48008b193f4e87b9ec04d5c8736ce0725d006/src/main/scala/com/nicta/scoobi/core/WireFormat.scala#L137). Despite the function having its own explicit return type, the type of the assigned value was not being inferred correctly by the compiler.
Below is the full example from the question with such a Serializer-generator.
package mypackage
import java.io.{DataOutput, DataOutputStream}
object Main {
import Serializer._
def main(args: Array[String]): Unit = {
val caseClassInstance = MyCaseClass("string")
val out: DataOutput = new DataOutputStream(System.out)
serialize(out, caseClassInstance)
}
def serialize[T : Serializer](out: DataOutput, t: T): Unit = {
implicitly[Serializer[T]].write(out, t)
}
}
object MyCaseClass {
import Serializer._
// does not compile without Serializer[MyCaseClass] type annotation
implicit val serializer: Serializer[MyCaseClass] =
mkCaseSerializer(MyCaseClass.apply _, MyCaseClass.unapply _)
}
case class MyCaseClass(s: String)
trait Serializer[T] {
def write(out: DataOutput, t: T): Unit
}
object Serializer {
// does not compile without Serializer[String] type annotation
implicit val stringSerializer: Serializer[String] = new Serializer[String] {
override def write(out: DataOutput, s: String): Unit = {
out.writeUTF(s)
}
}
class CaseClassSerializer[T, A : Serializer](
apply: A => T, unapply: T => Option[A]) extends Serializer[T] {
override def write(out: DataOutput, t: T): Unit = {
implicitly[Serializer[A]].write(out, unapply(t).get)
}
}
def mkCaseSerializer[T, A : Serializer]
(apply: A => T, unapply: T => Option[A]): Serializer[T] =
new CaseClassSerializer(apply, unapply)
}
This related, simple code below prints 1.
object A{
implicit def A2Int(a:A)=a.i1
}
case class A(i1:Int,i2:Int)
object Run extends App{
val a=A(1,2)
val i:Int=a
println(i)
}