I have an enum Fruit defined as:
object Fruit extends Enumeration {
val Apple, Banana, Cherry = Value
}
Now printing values of this enum, on Scala 2.7.x gives:
scala> Fruit foreach println
line1$object$$iw$$iw$Fruit(0)
line1$object$$iw$$iw$Fruit(1)
line1$object$$iw$$iw$Fruit(2)
However the same operation on Scala 2.8 gives:
scala> Fruit foreach println
warning: there were deprecation warnings; re-run with -deprecation for details
Apple
Banana
Cherry
My question is:
How is the method toString in Enumeration in Scala 2.8 implemented? I tried looking into the source of Enumeration but couldn't understand anything.
The implementation is based on the Java reflection API.
If you define val for the enum values:
object Fruit extends Enumeration {
val Apple, Banana, Cherry = Value
}
There are methods for the val in the class Fruit:
scala> Fruit.getClass.getMethods filter (_.getName.contains("Apple")) foreach println
public scala.Enumeration$Value line10$object$$iw$$iw$Fruit$.Apple()
toString calls Enumeration.this.nameOf(i) if the name is not explicitly set. This method will try to find all methods in the enumeration class returning Value instances.
val methods = getClass.getMethods
for (m <- methods
if (classOf[Value].isAssignableFrom(m.getReturnType) &&
!java.lang.reflect.Modifier.isFinal(m.getModifiers) &&
m.getParameterTypes.isEmpty &&
isValDef(m)))
These are the methods of the Fruit class.
It then takes the name of the methods and the ids of enum values to build a map id -> name and retrieves the name from the map with the id of enum value.
val name = m.getName
// invoke method to obtain actual `Value` instance
val value = m.invoke(this)
// invoke `id` method
val idMeth = classOf[Val].getMethod("id")
val id: Int = idMeth.invoke(value).asInstanceOf[java.lang.Integer].intValue()
This implementation can be easily broken if you define a enum like this:
object X extends Enumeration {
val Y = Value
}
object Fruit extends Enumeration {
val x = X.Y
val A,B,C = Value
}
This Fruit.value returns object$Fruit.ValueSet(x, B, C) not object$Fruit.ValueSet(A, B, C).
In Scala 2.8.0.RC2 you can find the implementation of toString in the inner class Val in line 273 of Enumeration.scala. The instances of Val are instantiated through the Value method in line 192. Currently I don't understand how the names (Apple, Banana, ...) are extracted. May somebody can help out?
Related
Supposedly I have the following
case class test {
a:string
b: string
c: Int
d: Int }
var temp = List(test("lol","lel",1,2))
var total = List(test)
total = total:::temp //this doesn't work because temp is of type [test] while total is of type [test.type]
I do not understand the difference.
The reason I want to use this is that I want to have a running list where elements will be conditionally added in a loop.
So in this instance, total should initially an empty list which takes test objects. How do I do this?
Any feedback is appreciated!
Let me begin by explaining few basics about Scala.
In Scala, you define a class like following,
scala> class Demo(a: String, b: Int) {
| def stringify: String = a + " :: " + b
| }
// defined class Demo
You can think of a class as a blueprint given to Scala which will be used to create instances of that class. Here, every instance of class Demo will have two properties - a which will be a String and b which will be an Int and one method - stringify which will return a String.
scala> val demo1 = new Demo("demo1", 1)
// demo1: Demo = Demo#21eee94f
scala> demo1.getClass
// res0: Class[_ <: Demo] = class Demo
Here demo1 is an instance of class Demo and has type Demo.
Scala also has a concept of object which are instances of specially generated inner classes.
scala> object OtherDemo {
| val a: Int = 10
| }
// defined object OtherDemo
scala> DemoObject.getClass
// res2: Class[_ <: OtherDemo.type] = class OtherDemo$
Here OtherDemo will be the only instance of that specially generated class OtherDemo$ and has type OtherDemo.type.
And then there are case class in Scala
scala> case class AnotherDemo(a: Int)
// defined class AnotherDemo
This will create not only a class AnotherDemo but also an object AnotherDemo which we call a companion object. Which is equivalent to,
class AnotherDemo(a: Int)
object AnotherDemo {
def apply(a: Int): AnotherDemo = new AnotherDemo(a)
def unapply(anotherDemo: AnotherDemo): Option[Int] = Some(anotherDemo.a)
// And many more utility functions
}
We call this object AnotherDemo as companion object of class AnotherDemo.
We can create instances of AnotherDemo in two ways,
// By using new keyword, as we can do for any class
scala> val anotherDemo1 = new AnotherDemo(1)
// anotherDemo1: AnotherDemo = AnotherDemo(1)
// Or we can use `apply` method provided by companion object
scala> val anotherDemo2 = AnotherDemo(2)
// anotherDemo2: AnotherDemo = AnotherDemo(2)
scala> anotherDemo1.getClass
// res6: Class[_ <: AnotherDemo] = class AnotherDemo
scala> anotherDemo2.getClass
// res7: Class[_ <: AnotherDemo] = class AnotherDemo
scala> AnotherDemo.getClass
// res8: Class[_ <: AnotherDemo.type] = class AnotherDemo$
Also, In Scala your class names should start with Capital Letter. This enables you to easily distinguish them from instance variable which should start with small letters. This helps you in avoiding confusion.
Now, it is supposed to be a: String and not a: string.
scala> case class Test(
| a: String,
| b: String,
| c: Int,
| d: Int
| )
// defined class Test
Now, when you write,
scala> var temp = List(Test("lol","lel",1,2))
// temp: List[Test] = List(Test(lol,lel,1,2))
It is actually equivalent to,
var temp = List.apply(Test.apply("lol","lel",1,2))
Or,
val test1 = Test.apply("lol","lel",1,2)
var temp = List.apply(test1)
The Test in Test.apply is not your class Test but the companion object Test. And calling Test.apply returns an instance of class Test which is being passed to List.apply to finally get a List of type List[Test] containing this instance of Test.
But when you write this,
scala> var total = List(Test)
// total: List[Test.type] = List(Test)
You are creating a List of type List[Test.type] containing that companion object of Test.
Focus on total: List[Test.type] part... this means that total is a variable of type List[Test.type] which means that it will want to point to a value/instance of type List[Test.type], and will refuse to point to anything else.
Now... you are trying to do this,
total = total ::: temp
Which is equivalent to,
val x = total ::: temp
total = x
which is actually,
val x = temp.:::(total)
total = x
Now look at this val x = total ::: temp,
scala> val x = total ::: temp
// x: List[Serializable] = List(Test, Test(lol,lel,1,2))
You see... this x is of type List[Serializable]. So when you try total = x, you will get following error,
scala> total = x
// <console>:13: error: type mismatch;
// found : List[Serializable]
// required: List[Test.type]
// total = x
// ^
Which means that total required a List[Test.type] but you are giving it a List[Serializable].
You are looking for total = List.empty[test] rather than List(test).
The former creates an empty list of type List[test], the latter is a one-element list of type List[test.type] (test.type is not the same as test - it is its own object, representing the type of instances of test).
Also, do not use var. They are evil, and not really needed in scala in 99% of uses-cases. Just pretend that keyword does not exist at all, until you get enough of a grip at the language to be able to confidently distinguish the other 1%.
When you do this:
var total = List(test)
You are not initializing the object test, that's why the type of the list is Test.type, you are only creating a list of a template for an object.
When you do this instead:
var temp = List(test("lol","lel",1,2))
Yo have the object instantiated from a template (a class, in this case, Test) so the type of temp is List[Temp].
So, if you do something like:
val template = Test
Then the type of t is Test.type
And you can instantiate an object Test from template like this:
val instantiated = template("lol","lel",1,2)
As you see in your example, the total variable is just a list of templates from where you can instantiate objects while the temp variable is a list of objects of type Test.
To create an empty list of objects of type Test you just have to do:
val t: List[Test] = List.empty
Then you can add any object (of type Test) to this list
Based on your description ('I want to have a running list where elements will be conditionally added in a loop'), my understanding is that you are getting Test objects from some source and want to put them in a list but only if they meet certain criteria. We can express this requirement as a method. For convenience, we'll put the method in the Test companion object. Companion objects are a place to put things that should be available without having to instantiate any objects.
case class Test(a: String, b: String, c: Int, d: Int)
object Test {
/**
Returns a list of `Test` objects that pass the given criteria.
#param tests some source of tests that we can loop over one at a
time.
#param condition checks whether a `Test` object should go into our
output list.
*/
def runningList(
tests: Iterable[Test])(condition: Test => Boolean): List[Test] =
tests.filter(condition).toList
}
You can use it like (e.g.):
Test.runningList(testsSource) { test => test.c > 0 && test.d < 100 }
As you can see here, I've used a few Scala features, like iterables and their list conversion method, multi-parameter-list methods, first-class functions, function-as-last-argument DSL, and so on. If you have more questions on these topics I'd recommend a Scala tutorial.
I'm trying to use discriminators in existing project and something is wrong with my classes I guess.
Consider this scodec example. If I change TurnLeft and its codec to
sealed class TurnLeft(degrees: Int) extends Command {
def getDegrees: Int = degrees
}
implicit val leftCodec: Codec[TurnLeft] = uint8or16.xmap[TurnLeft](v => new TurnLeft(v), _.getDegrees)
I get
Error:(x, x) could not find Lazy implicit value of type scodec.Codec[Command]
val codec: Codec[Either[UnrecognizedCommand, Command]] = discriminatorFallback(unrecognizedCodec, Codec[Command])
It all works if I make degrees field value field. I suspect it's something tricky with shapeless. What should I do to make it work ?
Sample project that demonstrates the issue is here.
shapeless's Generic is defined for "case-class-like" types. To a first approximation, a case-class-like type is one whose values can be deconstructed to it's constructor parameters which can then be used to reconstruct an equal value, ie.
case class Foo ...
val foo = Foo(...)
val fooGen = Generic[Foo]
assert(fooGen.from(fooGen.to(foo)) == foo)
Case classes with a single constructor parameter list meet this criterion, whereas classes which don't have public (lazy) vals for their constructor parameters, or a companion with a matching apply/unapply, do not.
The implementation of Generic is fairly permissive, and will treat (lazy) val members which correspond to constructor parameters (by type and order) as being equivalent to accessible constructor arguments, so the closest to your example that we can get would be something like this,
sealed class TurnLeft(degrees: Int) extends Command {
val getDegrees: Int = degrees
}
scala> Generic[TurnLeft]
res0: shapeless.Generic[TurnLeft]{type Repr = Int :: HNil } = ...
In this case getDegrees is treated as the accessor for the single Int constructor parameter.
This question already has answers here:
Scala - initialization order of vals
(3 answers)
Closed 7 years ago.
I'm seeing some initialization weirdness when mixing val's and def's in my trait. The situation can be summarized with the following example.
I have a trait which provides an abstract field, let's call it fruit, which should be implemented in child classes. It also uses that field in a val:
scala> class FruitTreeDescriptor(fruit: String) {
| def describe = s"This tree has loads of ${fruit}s"
| }
defined class FruitTreeDescriptor
scala> trait FruitTree {
| def fruit: String
| val descriptor = new FruitTreeDescriptor(fruit)
| }
defined trait FruitTree
When overriding fruit with a def, things work as expected:
scala> object AppleTree extends FruitTree {
| def fruit = "apple"
| }
defined object AppleTree
scala> AppleTree.descriptor.describe
res1: String = This tree has loads of apples
However, if I override fruit using a val...
scala> object BananaTree extends FruitTree {
| val fruit = "banana"
| }
defined object BananaTree
scala> BananaTree.descriptor.describe
res2: String = This tree has loads of nulls
What's going on here?
In simple terms, at the point you're calling:
val descriptor = new FruitTreeDescriptor(fruit)
the constructor for BananaTree has not been given the chance to run yet. This means the value of fruit is still null, even though it's a val.
This is a subcase of the well-known quirk of the non-declarative initialization of vals, which can be illustrated with a simpler example:
class A {
val x = a
val a = "String"
}
scala> new A().x
res1: String = null
(Although thankfully, in this particular case, the compiler will detect something being afoot and will present a warning.)
To avoid the problem, declare fruit as a lazy val, which will force evaluation.
The problem is the initialization order. val fruit = ... is being initialized after val descriptor = ..., so at the point when descriptor is being initialized, fruit is still null. You can fix this by making fruit a lazy val, because then it will be initialized on first access.
Your descriptor field initializes earlier than fruit field as trait intializes earlier than class, that extends it. null is a field's value before initialization - that's why you get it. In def case it's just a method call instead of accessing some field, so everything is fine (as method's code may be called several times - no initialization here). See, http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html
Why def is so different? That's because def may be called several times, but val - only once (so its first and only one call is actually initialization of the fileld).
Typical solution to such problem - using lazy val instead, it will intialize when you really need it. One more solution is early intializers.
Another, simpler example of what's going on:
scala> class A {val a = b; val b = 5}
<console>:7: warning: Reference to uninitialized value b
class A {val a = b; val b = 5}
^
defined class A
scala> (new A).a
res2: Int = 0 //null
Talking more generally, theoretically scala could analize the dependency graph between fields (which field needs other field) and start initialization from final nodes. But in practice every module is compiled separately and compiler might not even know those dependencies (it might be even Java, which calls Scala, which calls Java), so it's just do sequential initialization.
So, because of that, it couldn't even detect simple loops:
scala> class A {val a: Int = b; val b: Int = a}
<console>:7: warning: Reference to uninitialized value b
class A {val a: Int = b; val b: Int = a}
^
defined class A
scala> (new A).a
res4: Int = 0
scala> class A {lazy val a: Int = b; lazy val b: Int = a}
defined class A
scala> (new A).a
java.lang.StackOverflowError
Actually, such loop (inside one module) can be theoretically detected in separate build, but it won't help much as it's pretty obvious.
I have a list of simple scala case class instances and I want to print them in predictable, lexicographical order using list.sorted, but receive "No implicit Ordering defined for ...".
Is there exist an implicit that provides lexicographical ordering for case classes?
Is there simple idiomatic way to mix-in lexicographical ordering into case class?
scala> case class A(tag:String, load:Int)
scala> val l = List(A("words",50),A("article",2),A("lines",7))
scala> l.sorted.foreach(println)
<console>:11: error: No implicit Ordering defined for A.
l.sorted.foreach(println)
^
I am not happy with a 'hack':
scala> l.map(_.toString).sorted.foreach(println)
A(article,2)
A(lines,7)
A(words,50)
My personal favorite method is to make use of the provided implicit ordering for Tuples, as it is clear, concise, and correct:
case class A(tag: String, load: Int) extends Ordered[A] {
// Required as of Scala 2.11 for reasons unknown - the companion to Ordered
// should already be in implicit scope
import scala.math.Ordered.orderingToOrdered
def compare(that: A): Int = (this.tag, this.load) compare (that.tag, that.load)
}
This works because the companion to Ordered defines an implicit conversion from Ordering[T] to Ordered[T] which is in scope for any class implementing Ordered. The existence of implicit Orderings for Tuples enables a conversion from TupleN[...] to Ordered[TupleN[...]] provided an implicit Ordering[TN] exists for all elements T1, ..., TN of the tuple, which should always be the case because it makes no sense to sort on a data type with no Ordering.
The implicit ordering for Tuples is your go-to for any sorting scenario involving a composite sort key:
as.sortBy(a => (a.tag, a.load))
As this answer has proven popular I would like to expand on it, noting that a solution resembling the following could under some circumstances be considered enterprise-gradeā¢:
case class Employee(id: Int, firstName: String, lastName: String)
object Employee {
// Note that because `Ordering[A]` is not contravariant, the declaration
// must be type-parametrized in the event that you want the implicit
// ordering to apply to subclasses of `Employee`.
implicit def orderingByName[A <: Employee]: Ordering[A] =
Ordering.by(e => (e.lastName, e.firstName))
val orderingById: Ordering[Employee] = Ordering.by(e => e.id)
}
Given es: SeqLike[Employee], es.sorted() will sort by name, and es.sorted(Employee.orderingById) will sort by id. This has a few benefits:
The sorts are defined in a single location as visible code artifacts. This is useful if you have complex sorts on many fields.
Most sorting functionality implemented in the scala library operates using instances of Ordering, so providing an ordering directly eliminates an implicit conversion in most cases.
object A {
implicit val ord = Ordering.by(unapply)
}
This has the benefit that it is updated automatically whenever A changes. But, A's fields need to be placed in the order by which the ordering will use them.
To summarize, there are three ways to do this:
For one-off sorting use .sortBy method, as #Shadowlands have showed
For reusing of sorting extend case class with Ordered trait, as #Keith said.
Define a custom ordering. The benefit of this solution is that you can reuse orderings and have multiple ways to sort instances of the same class:
case class A(tag:String, load:Int)
object A {
val lexicographicalOrdering = Ordering.by { foo: A =>
foo.tag
}
val loadOrdering = Ordering.by { foo: A =>
foo.load
}
}
implicit val ord = A.lexicographicalOrdering
val l = List(A("words",1), A("article",2), A("lines",3)).sorted
// List(A(article,2), A(lines,3), A(words,1))
// now in some other scope
implicit val ord = A.loadOrdering
val l = List(A("words",1), A("article",2), A("lines",3)).sorted
// List(A(words,1), A(article,2), A(lines,3))
Answering your question Is there any standard function included into the Scala that can do magic like List((2,1),(1,2)).sorted
There is a set of predefined orderings, e.g. for String, tuples up to 9 arity and so on.
No such thing exists for case classes, since it is not easy thing to roll off, given that field names are not known a-priori (at least without macros magic) and you can't access case class fields in a way other than by name/using product iterator.
The unapply method of the companion object provides a conversion from your case class to an Option[Tuple], where the Tuple is the tuple corresponding to the first argument list of the case class. In other words:
case class Person(name : String, age : Int, email : String)
def sortPeople(people : List[Person]) =
people.sortBy(Person.unapply)
The sortBy method would be one typical way of doing this, eg (sort on tag field):
scala> l.sortBy(_.tag)foreach(println)
A(article,2)
A(lines,7)
A(words,50)
Since you used a case class you could extend with Ordered like such:
case class A(tag:String, load:Int) extends Ordered[A] {
def compare( a:A ) = tag.compareTo(a.tag)
}
val ls = List( A("words",50), A("article",2), A("lines",7) )
ls.sorted
My personal favorite method is using the SAM(Single abstraction method) with 2.12 as mentioned over the below example:
case class Team(city:String, mascot:String)
//Create two choices to sort by, city and mascot
object MyPredef3 {
// Below used in 2.11
implicit val teamsSortedByCity: Ordering[Team] = new Ordering[Team] {
override def compare(x: Team, y: Team) = x.city compare y.city
}
implicit val teamsSortedByMascot: Ordering[Team] = new Ordering[Team] {
override def compare(x: Team, y: Team) = x.mascot compare y.mascot
}
/*
Below used in 2.12
implicit val teamsSortedByCity: Ordering[Team] =
(x: Team, y: Team) => x.city compare y.city
implicit val teamsSortedByMascot: Ordering[Team] =
(x: Team, y: Team) => x.mascot compare y.mascot
*/
}
object _6OrderingAList extends App {
//Create some sports teams
val teams = List(Team("Cincinnati", "Bengals"),
Team("Madrid", "Real Madrid"),
Team("Las Vegas", "Golden Knights"),
Team("Houston", "Astros"),
Team("Cleveland", "Cavaliers"),
Team("Arizona", "Diamondbacks"))
//import the implicit rule we want, in this case city
import MyPredef3.teamsSortedByCity
//min finds the minimum, since we are sorting
//by city, Arizona wins.
println(teams.min.city)
}
For purposes of my app I need to be able to find out a list of fields of a type (not an instance) and types of those fields in runtime. So far I was only able to get a list of methods of a case class containing getters with classOf[MyCaseClass].getMethods and nothing useful from a simple class. Am I missing something? Are there any reflection libraries for that kinda purposes? How's that done correctly?
Using Scala 2.10 reflection:
scala> import reflect.runtime.{universe => ru}
import reflect.runtime.{universe=>ru}
scala> trait A { val field1: Int; val field2: Char; def meth1: Int }
defined trait A
scala> val fieldSymbols = ru.typeOf[A].members.collect{ case m: ru.MethodSymbol if m.isGetter => m }
fieldSymbols: Iterable[reflect.runtime.universe.MethodSymbol] = List(value field2, value field1)
The returned symbols contain all the type information, e.g.:
scala> fieldSymbols.map(_.typeSignature)
res16: Iterable[reflect.runtime.universe.Type] = List(=> scala.Char, => scala.Int)
You may want to take a look at this document on reflecting scala. getMethods is a method from Java reflection. What can't you find there? From the Javadoc:
String getName(): Returns the name of the method represented by this Method object, as a String.
Class[] getParameterTypes(): Returns an array of Class objects that represent the formal parameter types, in declaration order, of the method represented by this Method object.
Class getReturnType(): Returns a Class object that represents the formal return type of the method represented by this Method object.
You could read more about Java reflection.
Note that not all type information will be available at runtime because of erasure.