For pedagogical purposes I have implemented an enumeration using both Enumeration and case objects. I'm comfortable with the Enumeration version, although it cannot warn of missing cases in a match statement.
I have tried to write the equivalent using case objects but I am finding that, although it compiles, it doesn't run. In particular, it seems to go into an infinite loop at run time (I haven't been able to confirm this in the debugger, however). Here's the code I'm trying to run:
sealed abstract class Suit extends Ordered[Suit] {
val name: String
val priority: Int
override def toString = name
def compare(that: Suit) = priority-that.priority
}
case object Spades extends Suit { val name = "Spades"; val priority = 0 }
case object Hearts extends Suit { val name = "Hearts"; val priority = 1 }
case object Diamonds extends Suit { val name = "Diamonds"; val priority = 2 }
case object Clubs extends Suit { val name = "Clubs"; val priority = 3 }
object Suit {
implicit def ordering[A <: Suit]: Ordering[A] = Suit.ordering
def suits = List(Clubs,Spades).sorted
}
If I enter this code into the REPL (via paste mode) or if I compile it in Eclipse, all appears well. But if I try to test the suits method of the Suit object, the run just hangs and I have to terminate it.
I have tried most if not all of the suggestions I've found here on StackOverflow regarding implicits (for instance, not defining Suit class to extend Ordered[Suit] and instead specifying an Ordering directly for the class. None of these have compiled however.
Working suggestions much appreciated.
object Suit {
implicit def ordering[A <: Suit]: Ordering[A] = Suit.ordering
}
That is an infinite loop, ordering calls itself. I think you want an Ordering[Suit], it doesn't make sense in this case to ask for an ordering of a sub-type A of Suit (that would be one individual case object).
There is already an implicit ordering for types that extend Ordered, so you won't even need to construct one:
implicitly[Ordering[Suit]] // aka Ordering.ordered[Suit]
So the following just works:
object Suit {
def suits = List[Suit](Clubs, Spades).sorted
}
Note that List(Clubs, Spades).sorted won't work, because the inferred list element type is Suit with Product and somehow that produces a failure to find an unambiguous ordering.
Part of the problem that I had before was that Suit actually extends a trait called Concept, which I hadn't shown here (in an attempt to simplify things).
However, it actually allows a slight improvement on 0__'s answer because I no longer have to explicitly set the type of my list. Here is the code, at least the relevant parts:
trait Concept extends Ordered[Concept]{
val name: String
val priority: Int
override def toString = name
def compare(that: Concept) = priority-that.priority
}
sealed trait Suit extends Concept {
}
object Concept {
implicit def ordering[A <: Concept]: Ordering[A] = Ordering.by(_.priority)
}
case object Spades extends Suit { val name = "Spades"; val priority = 0 }
case object Hearts extends Suit { val name = "Hearts"; val priority = 1 }
case object Diamonds extends Suit { val name = "Diamonds"; val priority = 2 }
case object Clubs extends Suit { val name = "Clubs"; val priority = 3 }
object Suit {
import scala.math.Ordered.orderingToOrdered
def suits = List(Clubs,Spades).sorted
}
Related
I have a case class
case class InputCriteria(a: Int) {
val b: Int = config.getInt("some path")
}
How to mock this case class and override the value of b?
From scalamock faq:
Can I mock val / lazy val?
No, the Scala compiler will not allow overriding a val with a def, so with ScalaMock this is not possible. An option we are looking at for a possible future version of ScalaMock is scala.meta, but this is not yet available for all build targets we want. If you can, it is better to design a trait with a def and mock that instead. The concrete implementation can still override that def with a val to give invariant behaviour.
If you change your case class to trait you'd be able to override val with proxy.MockFactory.
If you changed you val to def you'd be able to override with plain mock.
You could also use the approach from Raman's answer, so unless you would want to make your class final it's working solution.
But what you should really do in my opinion is just creating trait:
trait InputCriteria {
def b: Int
}
and then implementing it:
case class ConfigDrivenInputCriteria(config: Config) extends InputCriteria {
override val b: Int = config.getInt("some path")
}
Then in test you could just reimplement it:
val testInputCritria = new InputCriteria {
override def b: Int = 4
}
but it might be a little bit clunky if you've got a lot of fields in InputCriteria, but in that case you could also mock it:
val inputCriteria = stub[InputCriteria]
(inputCriteria.b _).when().returns(100)
Interface + implementation approach gives you the ability to test your code easily. You can also decide in implementing class if your properties should be defs, vals or lazy vals.
try this:
object abc extends App {
case class A() {
val x = 6
}
val a: A = new A() {
override val x = 9
}
println(A().x, a.x)
}
In the specification of value classes, it says:
A value class can only extend universal traits and cannot be extended itself. A universal trait is a trait that extends Any, only has defs as members, and does no initialization. Universal traits allow basic inheritance of methods for value classes, but they incur the overhead of allocation. For example
trait Printable extends Any {
def print(): Unit = println(this)
}
class Wrapper(val underlying: Int) extends AnyVal with Printable
val w = new Wrapper(3)
w.print() // actually requires instantiating a Wrapper instance
First Question
Now, I would take this to mean that the following (probably) does not require instantiation:
trait Marker extends Any
class Wrapper(val underlying: Int) extends AnyVal with Marker {
def print(): Unit = println(this) //unrelated to Marker
}
val w = new Wrapper(3)
w.print() //probably no instantiation as print is unrelated to Marker
Am I correct?
Second Question
And I would think there is an even chance as to whether this requires instantiation or not:
trait Printable extends Any {
def print(): Unit //no implementation
}
class Wrapper(val underlying: Int) extends AnyVal with Printable {
override def print() = println(this) //moved impl to value class
}
val w = new Wrapper(3)
w.print() // possibly requires instantiation
On the balance of probability, I would also think that no instantiation would be needed - am I correct?
Edit
I'd not thought about the exact implementation of print() in the example:
def print(): Unit = println(this)
Let's say that I used the following instead:
def print(): Unit = println(underlying)
Would these cause instantiations?
Am I correct?
No, we can see it if we emit the final compilation output with -Xprint:jvm:
<synthetic> object F$Wrapper extends Object {
final def print$extension($this: Int): Unit =
scala.Predef.println(new com.testing.F$Wrapper($this));
This is due to the fact println has a type signature requiring Any, so we're shooting ourselves in the foot here since we're effectively "treating the value class ttpe as another type".
Although the call is dispatched to the static method call:
val w: Int = 3;
F$Wrapper.print$extension(w)
We're still incurring the allocation inside print$extension.
If we stray away from using Wrapper.this, then your first assumption is indeed correct and we can see the compiler happily unwrap Wrapper:
<synthetic> object F$Wrapper extends Object {
final def print$extension($this: Int): Unit =
scala.Predef.println(scala.Int.box($this));
And the call site now looks like this:
val w: Int = 3;
com.testing.F$Wrapper.print$extension(w)
This is valid for both of your examples now, as there is no need for any dynamic dispatch on the created interface.
Suppose I have a trait Foo with several methods. I want to create a new trait which extends Foo but "wraps" each method call, for example with some print statement (in reality this will be something more complicated / I have a couple of distinct use cases in mind).
trait Foo {
def bar(x: Int) = 2 * x
def baz(y: Int) = 3 * y
}
I can do this manually, by overriding each method. But this seems unnecessarily verbose (and all too easy to call the wrong super method):
object FooWrapped extends FooWrapped
trait FooWrapped extends Foo {
override def bar(x: Int) ={
println("call")
super.bar(x)
}
override def baz(y: Int) ={
println("call")
super.baz(y)
}
}
scala> FooWrapped.bar(3)
call
res3: Int = 6
I was hoping to write a mixin trait, that I would be able to reuse with other traits, and use as:
trait FooWrapped extends Foo with PrintCall
That way I don't have to manually override each method (the mixin would do this for me).
Is it possible to write such a mixin trait in Scala? What would it look like?
Update Here is the macro. It was much less painful than I thought it will be because of quasiquotes. They are awesome. This code does only a little and you probably will have to improve it. It may not account some special situations. Also it assumes that neither parent class nor it's method has type params, it wraps only the methods of the given class or trait, but not it's parents methods, it may not work if you have auxilary constructors etc. Still I hope it will give you an idea of how to do that for your specific needs, making it working for all of the situations unfortunately is too big job for me right now.
object MacrosLogging {
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
def log_wrap[T](): T = macro log_impl[T]
def log_impl[T : c.WeakTypeTag](c: blackbox.Context)(): c.Expr[T] = {
import c.universe._
val baseType = implicitly[c.WeakTypeTag[T]].tpe
val body = for {
member <- baseType.declarations if member.isMethod && member.name.decodedName.toString != "$init$"
method = member.asMethod
params = for {sym <- method.paramLists.flatten} yield q"""${sym.asTerm.name}: ${sym.typeSignature}"""
paramsCall = for {sym <- method.paramLists.flatten} yield sym.name
methodName = member.asTerm.name.toString
} yield {
q"""override def ${method.name}(..$params): ${method.returnType} = { println("Method " + $methodName + " was called"); super.${method.name}(..$paramsCall); }"""
}
c.Expr[T] {q""" { class A extends $baseType { ..$body }; new A } """}
}
}
If you do not want to create an instance, but you do want to add logging only for your trait so you could mixin further, you can do this with relatively the same code, but using macro paradise type annotations: http://docs.scala-lang.org/overviews/macros/annotations These allow you to tag your class definitions and perform modifications right inside the definitions
You could do something like you want with Dynamic, but there is a catch - you can't make it of original type, so it's not a mixin. Dynamic starts to work only if type checks fails, so you can't mixin real type (or I do not know how to do that). The real answer would probably require macros (as #AlexeyRomanov suggested in comments), but I am not sure how to write one, maybe I'll come up with it later. Still Dynamic might work for you if you are not looking for DI here
trait Foo {
def bar(x: Int) = 2 * x
def baz(y: Int) = 3 * y
}
import scala.reflect.runtime.{universe => ru}
import scala.language.dynamics
trait Wrapper[T] extends Dynamic {
val inner: T
def applyDynamic(name: String)(args: Any*)(implicit tt: ru.TypeTag[T], ct: ClassTag[T]) = {
val im = tt.mirror.reflect(inner)
val method = tt.tpe.decl(ru.TermName(name)).asMethod
println(method)
val mm = im.reflectMethod(method)
println(s"$name was called with $args")
mm.apply(args:_*)
}
}
class W extends Wrapper[Foo] {
override val inner: Foo = new Foo() {}
}
val w = new W // Cannot be casted to Foo
println(w.bar(5)) // Logs a call and then returns 10
You can read more about Dynamic here: https://github.com/scala/scala/blob/2.12.x/src/library/scala/Dynamic.scala
I'm using Scala 2.10.4.
Please bare with the analogy - the actual code is deeply embedded in a complicated program, so rather than explain that, I’ll abstract the problem in a time honoured way to talk about Animals ;-)
In scala I have 2 traits - for example:
Animal, and HouseBase.
I have no access to change Animal, but I inherit from it with classes like Dog, Rabbit, Fish. Annoyingly I can’t change every subclass as I don’t own all the subclasses I use.
My animals all live somewhere - their homes must inherit from HouseBase. I can change HouseBase and it’s subclasses (via another layer of abstraction, if I must).
So a Dog is a subclass of Animal, and would live in a Kennel which is a subclass of HouseBase.
A Rabbit would live in a Hutch, and a Fish in a Tank.
Note there is not a 1:1 relationship enforced here - a Fish could also live in a Pond, and we’d have to be able to handle that too.
What I’d hoped was that -- given a concrete animal (eg Fish), that is referenced via an abstract type Animal, and given a concrete return type (eg Tank), Scala would be able to automagically pick the correct implicit parameter in the design I have below.
object AnimalSelectionProblem extends App {
def abstractFish : Animal = new Fish(true, 20.0)
def concreteFish : Fish = new Fish(false, 30.0)
def abstractDog : Animal = new Dog("tasty bone")
def concreteDog : Dog = new Dog("yummy bone")
def abstractRabbit : Animal = new Rabbit(5)
def concreteRabbit : Rabbit = new Rabbit(10)
import HouseImplicits._
val myTank1: Tank = HouseImplicits.create(abstractFish)
val myTank2: Tank = HouseImplicits.create(concreteFish)
val myKennel1: Kennel = HouseImplicits.create(abstractDog)
val myKennel2: Kennel = HouseImplicits.create(concreteDog) // This works
val myhutch1: Hutch = HouseImplicits.create(abstractRabbit)
val myhutch2: Hutch = HouseImplicits.create(concreteRabbit) // This works
}
However there are 2 related problems.
Problem 1 - If the animal is referenced as an abstract, then the implicit parameter will only look for functions that take the abstract type (Animal) rather than the underlying concrete type. I suspect the solution may be to use ClassTags, because Scala doesn’t seem to use runtime time information? I had a go at implementing this and got hopelessly l lost (I’m fairly new to Scala!).
Problem 2 - If my animal can live in more than one type of House then a similar issue occurs, that even if a concrete return type is specified, the compiler will find the 2 implicit objects for Fish ambiguous. I’m a bit stumped about what to do here!
I can dream up solutions with manual boilerplate to match the type at runtime, but this isn’t very extensible.
Any ideas gratefully received! Rest of the code is below.
Edit - these links seems to confirm what I had suspected. That compile time polymorphism is used and hence the runtime type cannot be known:
http://like-a-boss.net/2013/03/29/polymorphism-and-typeclasses-in-scala.html
https://softwareengineering.stackexchange.com/questions/258698/is-it-possible-to-have-ad-hoc-polymorphism-with-runtime-dispatch
So, I guess my question now is, given this, is there a way to modify my example to use runtime dispatch?
Animals:
trait Animal {
}
class Dog(val boneName: String) extends Animal
class Rabbit(val length: Int) extends Animal
class Fish(val likesFrogs: Boolean, val optimumTemp: Double) extends Animal
Houses and Implicits:
sealed trait HouseBase
// Made up some arbitrary member variables
case class Kennel(posessions: Seq[String]) extends HouseBase
case class Hutch(length: Int) extends HouseBase
case class Tank(waterTemp: Double) extends HouseBase
case class Pond(containsFrog: Boolean) extends HouseBase
sealed trait HouseCreator[A <: Animal, HB <: HouseBase] {
def create(animal: A): HB
}
object HouseImplicits {
implicit object BuildKennelForDog extends HouseCreator[Dog, Kennel] {
override def create(dog: Dog): Kennel = {
new Kennel(Seq(dog.boneName))
}
}
implicit object BuildTankForFish extends HouseCreator[Fish, Tank] {
override def create(fish: Fish): Tank = {
new Tank(fish.optimumTemp)
}
}
implicit object BuildPondForFish extends HouseCreator[Fish, Pond] {
override def create(fish: Fish): Pond = {
new Pond(fish.likesFrogs)
}
}
implicit object BuildHutchForRabbit extends HouseCreator[Rabbit, Hutch] {
override def create(rabbit: Rabbit): Hutch = {
new Hutch(rabbit.length*5)
}
}
def create[A <: Animal, H <: HouseBase](animal: A)(implicit house: HouseCreator[A,H]) : H = {
val newHouse = house.create(animal)
newHouse
}
}
So basically you want the following design:
At compile time the concrete type of HouseBase is known.
At compile time the concrete type of Animal is not known.
Create a specific type HouseBase for Animal provided runtime animal data.
Can't change Animal implementations, and don't really want to change HouseBase implementations.
The desirable thing is of course to have the concrete types of Animals available at compile time. Since there seems to be some knowledge of that (you know which HouseBase to create for an animal variable at compile time), you may try to use type-safe cast from shapeless to get an Option of a concrete Animal type.
But if it's not possible you have to use run-time dispatch of animals.
In that case I think the method create should have the following signature:
def create[HB <: HouseBase](animal: Animal): Option[HB]
You know the concrete type of the HouseBase so you may as well pass it as type parameter, and the return value is Option to account for a possible mismatch between the type of the provided animal and suitable animal types for a concrete HouseBase
One possible way to implement that is the following code with a single object that has all the knowledge about the production of HouseBases from Animals (it should be also possible to achieve the same thing by moving the creation code into companion objects of concrete HouseBases):
sealed trait HouseCreator[HB <: HouseBase] {
def create(animal: Animal): Option[HB]
}
object HouseCreator {
implicit object KennelCreator extends HouseCreator[Kennel] {
def create(animal: Animal): Option[Kennel] = animal match {
case dog: Dog => Some(Kennel(Seq(dog.boneName)))
case _ => None
}
}
implicit object HutchCreator extends HouseCreator[Hutch] {
def create(animal: Animal): Option[Hutch] = animal match {
case rabbit: Rabbit => Some(Hutch(rabbit.length * 5))
case _ => None
}
}
implicit object TankCreator extends HouseCreator[Tank] {
def create(animal: Animal): Option[Tank] = animal match {
case fish: Fish => Some(Tank(fish.optimumTemp))
case _ => None
}
}
implicit object PondCreator extends HouseCreator[Pond] {
def create(animal: Animal): Option[Pond] = animal match {
case fish: Fish => Some(Pond(fish.likesFrogs))
case _ => None
}
}
def create[HB <: HouseBase : HouseCreator](animal: Animal): Option[HB] =
implicitly[HouseCreator[HB]].create(animal)
}
Then you can call the functions this way:
val myTank1: Option[Tank] = HouseCreator.create[Tank](abstractFish)
val myTank2: Option[Tank] = HouseCreator.create[Tank](concreteFish)
// Types of the variables can also be inferred automatically
val myKennel1 = HouseCreator.create[Kennel](abstractDog)
val myKennel2 = HouseCreator.create[Kennel](concreteDog)
val myhutch1 = HouseCreator.create[Hutch](abstractRabbit)
val myhutch2 = HouseCreator.create[Hutch](concreteRabbit)
Also, the boilerplate code in HouseCreator can be reduced by using PartialFunctions:
sealed trait HouseCreator[HB <: HouseBase] {
def create: PartialFunction[Animal, HB]
}
object HouseCreator {
implicit object KennelCreator extends HouseCreator[Kennel] {
def create = {
case dog: Dog => Kennel(Seq(dog.boneName))
}
}
implicit object HutchCreator extends HouseCreator[Hutch] {
def create = {
case rabbit: Rabbit => Hutch(rabbit.length * 5)
}
}
implicit object TankCreator extends HouseCreator[Tank] {
def create = {
case fish: Fish => Tank(fish.optimumTemp)
}
}
implicit object PondCreator extends HouseCreator[Pond] {
def create = {
case fish: Fish => Pond(fish.likesFrogs)
}
}
def create[HB <: HouseBase : HouseCreator](animal: Animal): Option[HB] =
implicitly[HouseCreator[HB]].create.lift(animal)
}
What you want is for the compiler to deduce the run-time type of your subclass when it is declared statically as an instance of its superclass. This is provably impossible, so don't try to make it work unless you're hoping to win some kind of computer science award!
Instead of parameterizing your HouseCreator class, you could write it to have a single create() method that accepts an object of type Animal. It could create the appropriate House using a case match that matches based on the run-time subtype of Animal.
sealed trait HouseCreator {
def create(animal: Animal): HouseBase {
animal match {
case dog: Dog => new Kennel(Seq(dog.boneName))
case fish: Fish => // etc...
}
}
}
This would only be able to return a HouseBase object rather than a specific subclass (at least as I implemented it here). You could always case match the return value as well.
I'd like to produce JSON for a List that includes both base classes and derived classes. The code below only produces JSON for the Animal class (I do not get the breed field for the Dog type members). Some help would be appreciated.
import play.api.libs.json._
class Animal (val name:String) {
}
object Animal {
implicit object animalWrite extends Writes[Animal] {
def writes(ts: Animal) = JsObject(Seq("name" -> JsString(ts.name)))
}
}
case class Dog (override val name:String, val breed: String)
extends Animal(name) {
}
object Dog {
implicit val format = Json.format[Dog]
}
case class Cat (override val name:String, val hairLength: Int)
extends Animal(name) {
}
object Cat {
implicit val format = Json.format[Cat]
}
object helloWorld extends App {
// The list below outputs: [{"name":"Ruff","breed":"labrador"}]
// val l = List[Dog](Dog("Ruff", "labrador"))
// The list below outputs: [{"name":"Ruff"},{"name":"Fluffy"}]
// I expect to see: [{"name":"Ruff","breed":"labrador"},{"name":"Fluffy","hairLength":3}]
val l = List[Animal](Dog("Ruff", "labrador"), Cat("Fluffy", 3))
println(Json.toJson(l))
}
Scala and Play newbie here, please excuse inappropriate use of terminology.
The json API extensively uses implicit parameters which is a feature of Scala where you can provide an "implicit" parameter list and if you don't specify those parameters the compiler will try to find an object in the current scope that is marked as implicit and matches that signature.
So if you for example would write:
implicit val s = "my implicit string"
def magicPrint(implicit message: String) { println(message) }
// and then call it
magicPrint
The compiler would select s for the parameter message since it is in scope and has the correct type (String), so after the implicit resolution the last line of code would actually look more like this
magicPrint(s)
The Format/Writer is selected by the compiler, at compile time, with an implicit parameter. If you look at the signature of the method, toJson[A](item: A)(implicit writes: Writes[A]), it takes an implicit Writes[A] which in your case is a Writes[List[Animal]] since List[Animal] is the type of your list l. Play contains a default has a writer that takes care of the collection (DefaultWrites.traversableWrites) which in turn takes an implicit Writes[A] - in your case Writes[Animal], so the compiler will select and pass your animalWrites.
That your list contains different types of animals is something that happens at runtime and the compiler has no way of knowing that from the type information available at your Json.toJson(l)
So, as you see you cannot achieve what you want in the way you thought, but you can do it in almost the same way by letting the animal writer know about the subtypes, for example:
implicit object animalWrite extends Writes[Animal] {
def writes(ts: Animal) = ts match {
// this will get an implicit Writes[Dog] since d is a Dog
case d: Dog => Json.toJson(d)
// this will get an implicit Writes[Cat] since c is a Cat
case c: Cat => Json.toJson(c)
case x => throw new RuntimeException(s"Unknown animal $x")
}
}
Hope this helped!