To clarify: I am NOT asking what I can use a Singleton design pattern for. The question is about largely undocumented trait provided in scala.
What is this trait for? The only concrete use case I could find so far was to limit a trait to objects only, as seen in this question: Restricting a trait to objects?
This question sheds some light on the issue Is scala.Singleton pure compiler fiction?, but clearly there was another use case as well!
Is there some obvious use that I can't think of, or is it just mainly compiler magicks?
I think the question is answered by Martin Odersky's comment on the mailing list thread linked to from the linked question:
The type Singleton is essentially an encoding trick for existentials
with values. I.e.
T forSome { val x: T }
is turned into
[x.type := X] T forSome { type X <: T with Singleton }
Singleton types are usually not used directly…
In other words, there is no intended use beyond guiding the typer phase of the compiler. The Scala Language Specification has this bit in §3.2.10, also §3.2.1 indicates that this trait might be used by the compiler to declare that a type is stable.
You can also see this with the following (Scala 2.11):
(new {}).isInstanceOf[Singleton]
<console>:54: warning: fruitless type test: a value of type AnyRef cannot also
be a Singleton
(new {}).isInstanceOf[Singleton]
^
res27: Boolean = true
So you cannot even use that trait in a meaningful test.
(This is not a definite answer, just my observation)
Related
I'm facing issues due to two scala compiler limitations
It's not possible to refer to the type of this (this.type is not it for obv reasons) for cases where you want to write traits which implement common behavior which requires construction of a concrete type. The recommended pattern to work around this is
trait Foo[SelfType <: Foo[SelfType]] {
this: SelfType =>
final def foo: SelfType = newInstance(??? /*do some work*/)
protected def newInstance(i: Int): SelfType
}
Scala compiler (fixed in Dotty AFAIK) does not keep track of bounds in existential types (I've found at least 3 bugs filed with the scala github project going back from 2009 and on). This means, given the above type if I were to write a method that take some unknown Foo as such
def process(f: Foo[_])
I may get some weird buggy compiler behavior in certain cases. Instead, I need to manually express to the compiler that the _ here obeys the type bounds to work around its limitations. For that, I'd need to do something like
def process[F <: Foo[F]](f: Foo[F])
and invoke the method without passing any type params which hopefully captures this correctly. However, this can make def signatures quite cumbersome if Foo takes other type params leading to a lot of burden for clients. So my question is, is it possible to use type definitions as a shorthand to express such self-referential types correctly. E.g. I've tried all sorts of things.
type SomeFoo = Foo[SelfType] with SelfType forSome { type SelfType <: Foo[SelfType] }
but that doesn't seem to quite do it. Somehow the compiler doesn't realize that SelfType is the same unknown type SomeFoo.
I hope this made sense. Thanks for your help. P.S. feel free to suggest renaming the question as it's not super clear right now.
trait foo[F] {
def test: F
}
class ah extends foo[(Int,Int) => Int] {
def test = (i: Int,j: Int) => i+j
}
So the question is, why Scala known to be so smart about types cannot just deduce type (Int,Int) => Int from the type of test asking me instead to specify it? Or It is still possible? Or maybe this is backed by some thoughts that I don't have in mind.
Your question is basically "why does Scala have only local type inference" or equivalently "why does Scala not have non-local type inference". And the answer is: because the designers don't want to.
There are several reasons for this. One reason is that the most reasonable alternative to local type inference is global type inference, but that's impossible in Scala: Scala has separate compilation and modular type checking, so there simply is no point in time where the compiler has a global view of the entire program. In fact, Scala has dynamic code loading, which means that at compile time the entire code doesn't even need to exist yet! Global type inference is simply impossible in Scala. The best we could do is "whole-compilation-unit type inference", but that is undesirable, too: it would mean that whether or not you need type annotations depends on whether or not you compile your code in multiple units or just one.
Another important reason is that type annotations at module boundaries serve as a double-check, kind of like double-entry book keeping for types. Note that even in languages with global type inference like Haskell, it is strongly recommended to put type annotations on module boundaries and public interfaces.
A third reason is that global type inference can sometimes lead to confusing error messages, when instead of the type checker failing at a type annotation, the type inferencer happily chugs along inferring increasingly non-sensical types, until it finally gives up at a location far away from the actual error (which might just be a simple typo) with a type error that is only tangentially related to the original types at the error site. This can sometimes happen in Haskell, for example. The Scala designers value helpful error messages so much that they are willing to sacrifice language features unless they can figure out how to implement them with good error messages. (Note that even with Scala's very limited type inference, you can get such "helpful" messages as "expected Foo got Product with Serializable".)
However, what Scala's local type inference can do in this example, is to work in the other direction, and infer the parameter types of the anonymous function from the return type of test:
trait foo[F] {
def test: F
}
class ah extends foo[(Int, Int) ⇒ Int] {
def test = (i, j) ⇒ i + j
}
(new ah) test(2, 3) //=> 5
For you particular example, inferring type parameters based on inheritance can be ambiguous:
trait A
trait B extends A
trait Foo[T] {
val x: T
}
trait Bar extends Foo[?] {
val x: B
}
The type that could go in the ? could be either A or B. This is a general example of where Scala will not infer types that could be ambiguous.
Now, you are correct to observe that there is a similarity between
class Foo[T](x: T)
and
trait Foo[T] { x: T }
I have seen work by some into possibly generalizing the similarity (but I can't seem to find it right now). That could, in theory, allow type inference of type parameters based on a member. But I don't know if it will ever get to that point.
I have a function with a type parameter and I want to find out whether the type parameter is an Option or not. I have read some blogposts, i.e. this one, about type classes in scala recently, so I came up with this solution:
case class OptionFinder[A](isOption: Boolean)
implicit def notOption[A]: OptionFinder[A] = OptionFinder(false)
implicit def hitOption[A]: OptionFinder[Option[A]] = OptionFinder(true)
def myFunction[A](value: A)(implicit optionFinder: OptionFinder[A]): String = {
if (optionFinder.isOption) {"Found Option!"} else {"Found something else."}
}
This works seemingly as desired:
scala> val x: Option[Int] = Some(3)
scala> myFunction(x)
res0: String = Found Option!
scala> val y: String = "abc"
scala> myFunction(y)
res1: String = Found something else.
In the case of Some(3) hitOption is the implicit parameter, even though notOption would match as well (with A = Option[Int]). Obviously the more specific is type chosen. But am I guaranteed that the compiler always chooses the more specific type? And how does that work in the compiler anyway? I did not find a documentation of this behavior yet.
Note: Maybe the title for this question is not best, I'll happily change it for a better one.
There is already a question about this: Scala: Implicit parameter resolution precedence. Which answers itself through a complicated blog post. I think the most important piece of information is in Martin Odersky's comment on the blog post:
Here's a more high-level explanation what goes on with implicit search
in Scala, and which corresponds to how the spec explains it, but in
slightly less formalistic language.
First, we look for implicits that are visible either as locals or as members of enclosing classes and packages or as imports - the
precise rule is that we should be able to access them using their name
only, without any prefix.
If no implicits are found in step 1, we look in the "implicit scope", which contains all sort of companion objects that bear some
relation to the type which we search for (i.e. companion object of the
type itself, of its parameters if any are given, and also of its
supertype and supertraits; the importance is to be as general as
possible without reverting to whole program analysis like Haskell
does).
If at either stage we find more than one implicit, disambiguation
kicks in. Disambiguation is exactly the same as for overloading
resolution. Static overloading resolution resolution rules are a bit
involved, and I won't repeat them here. If it's any consolation:
Java's rules and C#'s rules are considerably more complex than Scala's
in this area.
Now according to this explanation it are "the rules of static overloading resolution" which will disambiguate between notOption and hitOption. To be honest, I fail to see how.
This answer explains that indeed methods with more specific arguments have priority, but I don't know if or how that is related to the overloading rules.
If I were you I would not depend on this behavior too much, but use the easier to understand concept of implicit priority through inheritance. It's a good idea to put your implicits in the companion object anyway.
It boils down to the fact that implicits that are inherited have lower priority. So it's safe to put the implicit you fall back to if hitOption doesn't match in a trait that the companion object extends.
case class OptionFinder[A](isOption: Boolean)
object OptionFinder extends LowerPriority {
implicit def hitOption[A]: OptionFinder[Option[A]] = OptionFinder(true)
}
trait LowerPriority {
implicit def notOption[A]: OptionFinder[A] = OptionFinder(false)
}
def myFunction[A](value: A)(implicit optionFinder: OptionFinder[A]): String = {
if (optionFinder.isOption) {"Found Option!"} else {"Found something else."}
}
This should also work if you put your implicits in a non companion object MyImplicits and import them with import MyImplicits._.
Looking at scalaz.Tree[A], it is invariant in A. I'm looking for a multi-way tree which I can dump values of a hierarchy in
E.g. if I have an ADT of
trait MyThing
case object Thing1 extends MyThing
case object Thing2 extends MyThing
And I want a Tree of MyThings, I cant use this without doing a cast to MyThing in scalaz;
import scalaz.{Scalaz, Tree}
import Scalaz._
val tree = Thing1.asInstanceOf[MyThing].
node(Thing2.asInstanceOf[MyThing].leaf)
Which is a bit of a pain.
Is there are covariant [+A] version of Tree?
Why is Tree invariant in the first place?
First of all, I want to second Huw's recommendation that you use a type ascription instead of downcasting with asInstanceOf. As Huw says, using a type ascription will fail at compile time instead of runtime if something changes in your type hierarchy that makes the cast invalid. It's also just a good practice to avoid asInstanceOf for any upcasts. You can use asInstanceOf for either upcasting or downcasting, but only using it for downcasting makes it easy to identify unsafe casting in your code.
To answer your two questions—no, there's not a covariant tree type in Scalaz, for reasons discussed in detail in the pull request linked by Huw above. At first this may seem like a huge inconvenience, but the decision to avoid non-invariant structures in Scalaz is related to a similar design decision—avoiding the use of subtyping in ADTs—that makes invariant trees, etc. less painful.
In other languages with good support for ADTs (like Haskell and OCaml, for example), the leaves of an ADT aren't subtypes of the ADT type, and Scala's somewhat unusual subtyping-based implementation can make type inference messy. The following is a common example of this problem:
scala> List(1, 2, 3).foldLeft(None)((_, i) => Some(i))
<console>:14: error: type mismatch;
found : Some[Int]
required: None.type
List(1, 2, 3).foldLeft(None)((_, i) => Some(i))
^
Because the type of the accumulator is inferred from the first argument to foldLeft, it ends up as None.type, which is pretty much useless. You have to provide a type ascription (or explicit type parameters for foldLeft), which can be pretty inconvenient.
Scalaz attempts to address this issue by promoting the use of ADT constructors that don't return the most specific subtype for the ADT leaf. For example, it includes none[A] and some[A](a: A) constructors for Option that return an Option[A].
(For more discussion of these issues, see my answer here and this related question).
In your case, implementing this approach could be as simple as writing the following:
val thing1: MyThing = Thing1
val thing2: MyThing = Thing2
Which allows you to write thing1.node(thing2.leaf). If you want to go further down this path, I'd highly recommend looking at Argonaut's Json ADT as a good example of ADT design that downplays the role of subtyping.
Given a java class with two methods (taken from mockito):
OngoingStubbing<T> thenReturn(T value);
OngoingStubbing<T> thenReturn(T value, T... values);
If I invoke from scala with
....thenReturn("something")
I get an error:
Description Resource Path Location Type
ambiguous reference to overloaded definition, both method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object, x$2: <repeated...>[java.lang.Object])org.mockito.stubbing.OngoingStubbing[java.lang.Object] and method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object)org.mockito.stubbing.OngoingStubbing[java.lang.Object] match argument types (java.lang.String)
And I cannot figure out how to fix this.
This is a known Scala-Java interoperability problem, though it's unfortunately not in the FAQ. Here's the Scala ticket describing the problem. Essentially, both methods are applicable when you give a single argument, and the Scala compiler currently doesn't have any heuristic to decide which one is "more specific". Alexey Romanov's approach to always use the varargs version is a good workaround:
thenReturn("something", Nil: _*)
There is also a question running into a similar problem with JCommander. One of the answers there gives a clever workaround using structural types. This approach will use reflection behind the scenes, so you may or may not want to go that direction. For your use case, it would look something like:
type useSingleArgVersion = { def thenReturn(value: AnyRef): OngoingStubbing }
(...).asInstanceOf[useSingleArgVersion].thenReturn("something")
Finally, there is a similar question running into a similar problem with mokito. It doesn't really provide any workarounds, but it does describe the problem in a bit more detail, if you're interested in the reason this happens.
If calling the vararg version is acceptable,
thenReturn("something", Nil: _*)
Can't think of a way to call the method without varargs right now.
These answers are all to the wrong question. The difference is subtle, but this is not the same issue as the one in the linked ticket. That one does require unreasonable gymnastics to call the non-varargs method. For this one, the following is enough.
thenReturn[String]("something")
Or, if you didn't want to do that for some reason, you don't need the type alias and the cast. You can use a structural type ascription directly.
(this: { def thenReturn[T](s: T): OngoingStubbing[T] }).thenReturn("something")
The issue here is type inference at the intersection of overloading and polymorphism - one method is more specific, but scalac doesn't figure out which. The issue in SI-2991 is genuine ambiguity due to an interaction between overloading and tuple conversion - neither is more specific.
Assuming others will find this question when having the overloaded method value thenReturn with alternatives error, I want to share my solution as well.
Instead of
when(field.getValue(isA(classOf[Record]))).thenReturn(value)
I use
doReturn(value).when(field).getValue(isA(classOf[Record]))
which resolves the disambiguity in my case.
The workaround is quite easy:
OngoingStubbing<T> thenReturn(T value);
OngoingStubbing<T> thenReturn(T value1, T valu2, T... values);
There is no "varargs must be non empty" feature.
I tried Steve's solution and got a huge compiler error including:
scala.tools.nsc.symtab.Types$TypeError: type mismatch;
found : scala.reflect.Manifest[Nothing]
required: scala.reflect.ClassManifest[B]
Note: Nothing <: B, but trait ClassManifest is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: B`. (SLS 3.2.10)
I was able to make it work with something like:
thenReturn("something", Seq.empty[Object]: _*)