Given:
val personsOpt:Option[List[Person]] = ???
I prefer:
persons = personsOpt.fold(List[Person]()){person => person}
To this:
persons = personsOpt.getOrElse(List[Person]())
For type safety reasons. For example this does not compile:
persons = personsOpt.fold(Nil){person => person}
Is there a simple way to get the type safety but not have {person => person}?
EDIT: Two things now concretely understood:
There is nothing un-type-safe about getOrElse. For instance this does not compile: personsOpt.getOrElse("")
Nil is List() and if its type can't be inferred the compiler will ask you to be explicit. So there can be no type issues with using Nil
I couldn't find the link just now, but I did (incorrectly) read that getOrElse was somehow less type safe than using fold with an Option.
There is the function identity which is defined in Predef:
persons = personsOpt.fold(List[Person]())(identity)
I find this however a lot less readable than using getOrElse, and using this does not make your code more type-safe than using getOrElse. Note that passing Nil to getOrElse will make it return the correct type:
scala> case class Person(name: String)
scala> val personsOpt:Option[List[Person]] = None
personsOpt: Option[List[Person]] = None
scala> val persons = personsOpt.getOrElse(Nil)
persons: List[Person] = List()
Note that persons is a List[Person].
Related
I am following this tutorial on GraphQL with Sangria. I am wondering about the following line
val JsObject(fields) = requestJSON
where requestJSON is an object of JsValue. This way of assigning fields is new to me and my question is, if you could name that pattern or provide me with a link to a tutorial regarding this structure.
The important thing to know is that val definitions support a Pattern on the left-hand side of the assignment, thus providing (subset of the functionality of) Pattern Matching.
So, your example is equivalent to:
val fields = requestJSON match {
case JsObject(foo) => foo
}
See Scala Language Specification Section 4.1 Value Declarations and Definitions for details.
So, for example, if you have a list l and you want to assign the first element and the rest, you could write:
val x :: xs = l
Or, for the fairly common case where a method returns a tuple, you could write:
val (result1, result2) = foo()
It is the Extractor pattern, you can reach the same result implementing the unapply method on your arbitrary object (like shown in the example). When you create a case class the compiler produces an unapply method for you, so you can do:
case class Person(name : String, surname : String)
val person = Person("gianluca", "aguzzi")
val Person(name, surname) = person
I have a unit test, which test some solution. But this test code can also be applied for testing the other, very similar solution. What I want to make is code of test be generic to be applied to both solutions, like this:
describe("when table contains all correct rows") {
it("should be empty") {
def check[T](func: T => List[Row]) = {
val tableGen = new TableGenerator()
val table: Vector[Row] = tableGen.randomTable(100)
.sortWith(_.time isBefore _.time).distinct
val result: List[Row] = func(table)
assert(result.isEmpty)
}
check(Solution.solution1)
check(Solution.solution2)
}
}
where solutions have types:
solution1: IndexedSeq[Row] => List[Row]
solution2: Seq[Row] => List[Row]
how check() function has to be written to be able to do that?
And what's the best approaches to write this (might be in other way) with eliminated code duplication?
Update:
When I try to compile this code I get type mismatch error in func(table):
Error:(36, 29) type mismatch;
found : table.type (with underlying type scala.collection.immutable.Vector[com.vmalov.tinkoff.Row])
required: T
val result = func(table)
For this to work, you need to be able to pass a Vector[Row] to func, so any Vector[Row] has to be a T; that is, T is a supertype of Vector[Row]. You can tell this to the compiler by using a type parameter bound:
def check[T >: Vector[Row]](func: T => List[Row])
Alternately, by the above reasoning, a function T => List[Row] will also be a function Vector[Row] => List[Row] precisely when T is a supertype of Vector[Row], and the Scala compiler knows about this (functions are contravariant in their argument type(s)). So this signature is equivalent to simpler
def check(func: Vector[Row] => List[Row])
Of course, you can generalize this, but how much depends on your specific desires. E.g. you can replace List[Row] with Seq[Row] (everywhere), or with a type parameter and pass an extra function to check:
def check[A](func: Vector[Row] => A)(test: A => Boolean) = {
val table = ...
val result = func(table)
assert(test(result))
}
check(Solution.solution1)(_.isEmpty) // the compiler infers A is List[Row]
Your case, maybe is enough to abstract the type on a more specific way, like defining that you are expecting a Travesable.
def check[S[_] : Traversable](func: S[Row] => List[Row])
That would accept either Seq or IndexedSeq as valid parameter, while it also be limiting it.
I hope it helps
EDITED: Check Alexey Romanov Answer, as with this you will not be able to call func the way you do it. Sorry about that
def check(func: Vector[Row] => List[Row])
In Scala, when I want to set something to None, I have a couple of choices: using None or Option.empty[A].
Should I just pick one and use it consistently, or are there times when I should be using one over the other?
Example:
scala> def f(str: Option[String]) = str
f: (str: Option[String])Option[String]
scala> f(None)
res0: Option[String] = None
scala> f(Option.empty)
res1: Option[String] = None
I would stick to None whenever possible, which is almost always. It is shorter and widely used. Option.empty allows you to specify the type of underlying value, so use it when you need to help type inference. If the type is already known for the compiler None would work as expected, however while defining new variable
var a = None
would cause infering a as None.type which is unlikely what you wanted.
You can then use one of the couple ways to help infer what you need
# var a = Option.empty[String]
a: Option[String] = None
# var a: Option[String] = None
a: Option[String] = None
# var a = None: Option[String] // this one is rather uncommon
a: Option[String] = None
Another place when compiler would need help:
List(1, 2, 3).foldLeft(Option.empty[String])((a, e) => a.map(s => s + e.toString))
(Code makes no sense but just as an example) If you were to omit the type, or replace it with None the type of accumulator would be infered to Option[Nothing] and None.type respectively.
And for me personally this is the place I would go with Option.empty, for other cases I stick with None whenever possible.
Short answer use None if talking about a value for example when passing parameter to any function, use Option.empty[T] when defining something.
var something = Option.empty[String] means something is None for now but can become Some("hede") in the future. On the other hand var something = None means nothing. you can't reassign it with Some("hede") compiler will be angry:
found : Some[String]
required: None.type
So, this means None and Option.empty[T] are not alternatives. You can pass None to any Option[T] but you can't pass Some[T] to None.type
Given that Option[A].empty simply returns None:
/** An Option factory which returns `None` in a manner consistent with
* the collections hierarchy.
*/
def empty[A] : Option[A] = None
I'd say:
As you said, be consistent throughout the codebase. Making it consistent would mean that programmers entrying your codebase have one less thing to worry about. "Should I use None or Option.empty? Well, I see #cdmckay is using X throughout the call base, I'll use that as well"
Readability - think what conveys the point you want the most. If you were to read a particular method, would it make more sense to you if it returned an empty Option (let's disregard for a moment the fact that the underlying implementation is simply returning None) or an explicit None? IMO, I think of None as a non-existent value, as the documentation specifies:
/** This case object represents non-existent values.
*
* #author Martin Odersky
* #version 1.0, 16/07/2003
*/
Following are worksheet exports using Scala and Scalaz .
def f(str: Option[String]) = str //> f: (str: Option[String])Option[String]
f(None) //> res1: Option[String] = None
var x:Option[String]=None //> x : Option[String] = None
x=Some("test")
x //> res2: Option[String] = Some(test)
x=None
x
Now using Scalaz ,
def fz(str: Option[String]) = str //> fz: (str: Option[String])Option[String]
fz(none) //> res4: Option[String] = None
var xz:Option[String]=none //> xz : Option[String] = None
xz=some("test")
xz //> res5: Option[String] = Some(test)
xz=none
xz
Note that all the statements evaluate in the same way irrespective of you use None or Option.Empty. How ?
As you can see it is important to let Scala know of your intentions via the return type in the var x:Option[String]=None statement. This allows a later assignment of a Some. However a simple var x=None will fail in later lines because this will make the variable x resolve to None.type and not Option[T].
I would think that one should follow the convention. For assignments i would go for the var x:Option[String]=None option. Also whenever using None it is good to use a return type (in this case Option[String]) so that the assignment does not resolve to None.type.
Only in cases where i have no way to provide a type and i need some assignment done will i go for Option.empty
As everyone else pointed out, it's more a matter of personal taste, in which most of the people prefer None, or, in some cases, you explicitly need to put the type because the compiler can't infer.
This question can be extrapolated to other Scala classes, such as Sequences, Map, Set, List and so on. In all of them you have several ways to define empty state. Using sequence:
Seq()
Seq.empty
Seq.empty[Type]
From the 3, I prefer the second, because:
The first (Seq()) is error prone. It looks like if someone wanted to create a sequence and forgot to add the elements
The second (Seq.empty) is explicit about the desire of having an empty sequence
While the third (Seq.empty[Type]) is as explicit as the second, it is more verbose, so I don't use typically
I'm trying to get the classOf[the-abstract-class-Option], but instead I always get the classOf[the-Option-*object*]. How can I get the class of the abstract class instead?
Both Option.getClass and classOf[Option[_]] gives me class scala.Option$.
Edit: I needn't have asked this; all of a sudden, classOf[Option[_]] works fine, weird. /Edit
Background:
I'm trying to invoke via reflection a method that takes an Option[String] parameter.
It signature look like so: ...(..., anySectionId: Option[String], ...)...
Before I can invoke the method, I look it up via getDeclaredMethod. But to do that, I need a list of parameter types, which I construct by calling _.getClass on each argument I'm going to give to the method. But _.getClass returns classOf[None] or classOf[Some] for Option instances, which makes getDeclaredMethod fail, because (?) the signature is based on Option not Some/None.
Here's the code:
val clazz: Class[_] = Play.current.classloader.loadClass(className)
val paramTypes = arguments.map(_ match {
case None => Option.getClass // gives me the object, not the abstract class
case _: Some[_] => classOf[Option[_]] // this also gives me the object :-(
case x => x.getClass // results in None or Some for Option instances
})
val m: jl.reflect.Method = clazz.getDeclaredMethod("apply", paramTypes: _*)
and the last line above fails for a method with any Option parameter (otherwise everything works fine).
The best way is use Scala reflection.
The next best way is not to make work for yourself by trying to match the param types.
Using getClass fails for subtypes:
scala> class Foo
defined class Foo
scala> class Bar extends Foo
defined class Bar
scala> class Baz { def baz(f: Foo) = 1 }
defined class Baz
scala> val b = new Baz
b: Baz = Baz#d33eaa9
scala> val p = new Bar
p: Bar = Bar#406c5ca2
scala> classOf[Baz].getDeclaredMethod("baz", p.getClass)
java.lang.NoSuchMethodException: Baz.baz(Bar)
It's easier just to match on the name:
scala> classOf[Baz].getMethods.find(_.getName == "baz") map (_.invoke(b,p)) getOrElse -1
res5: Any = 1
or filter on the number of params for poor man's overloading resolution, then maybe filter on all args having conforming types.
The notation for accidentally getting the object is in fact:
scala> classOf[Option$]
res8: Class[Option$] = class scala.Option$
Answer: classOf[Option[_]]
Weird! Suddenly classOf[Option[_]] works. I feel sure I tested once or twice before I submitted the question :-( Perhaps the IDE didn't have time to save the file before I recompiled, weird.
I don't know if I should delete the question. Or perhaps I should leave it as is, in case classOf[Option[_]] isn't obvious to everyone.
Let's say I have a MyObject instance which is not initialized:
var a:MyObject = null
is this the proper way to initialize it to null?
Alternatives
Use null as a last resort. As already mentioned, Option replaces most usages of null. If you using null to implement deferred initialisation of a field with some expensive calculation, you should use a lazy val.
Canonical initialisation to null
That said, Scala does support null. I personally use it in combination with Spring Dependency Injection.
Your code is perfectly valid. However, I suggest that you use var t: T = _ to initialize t to it's default value. If T is a primitive, you get the default specific to the type. Otherwise you get null.
Not only is this more concise, but it is necessary when you don't know in advance what T will be:
scala> class A[T] { var t: T = _ }
defined class A
scala> new A[String].t
res0: String = null
scala> new A[Object].t
res1: java.lang.Object = null
scala> new A[Int].t
res2: Int = 0
scala> new A[Byte].t
res3: Byte = 0
scala> new A[Boolean].t
res4: Boolean = false
scala> new A[Any].t
res5: Any = null
Advanced
Using var t: T= null is a compile error if T is unbounded:
scala> class A[T] { var t: T = null }
<console>:5: error: type mismatch;
found : Null(null)
required: T
class A[T] { var t: T = null }
You can add an implicit parameter as evidence that T is nullable -- a subtype of AnyRef not a subtype of NotNull This isn't fully baked, even in Scala 2.8, so just consider it a curiousity for now.
scala> class A[T](implicit ev: Null <:< T) { var t: T = null }
defined class A
The canonical answer is don't use null. Instead, use an option type:
var a = None : Option[MyObject]
When you want to set it:
a = Some(foo)
And when you want to read from it, test for None:
a match {
case None => Console.println("not here")
case Some(value) => Console.println("got: "+value)
}
As David and retronym have already mentioned, it's a good idea to use Option in most cases, as Option makes it more obvious that you have to handle a no-result situation. However, returning Some(x) requires an object creation, and calling .get or .getOrElse can be more expensive than an if-statement. Thus, in high-performance code, using Option is not always the best strategy (especially in collection-lookup code, where you may look up a value very many times and do not want correspondingly many object creations). Then again, if you're doing something like returning the text of an entire web page (which might not exist), there's no reason not to use Option.
Also, just to add to retronym's point on generics with null, you can do this in a fully-baked way if you really mean it should be null:
class A[T >: Null] { var t: T = null }
and this works in 2.7 and 2.8. It's a little less general than the <:< method, because it doesn't obey NotNull AFAIK, but it otherwise does exactly what you'd hope it would do.
I came across this question since scalastyle told me to not use null when initialising an object within my test with null.
My solution without changing any type that satisfied scalastyle:
var a: MyObject = (None: Option[MyObject]).orNull