can some one please explain this line of codings from scala - scala

I am really struggling a lot to understand this line of code. can someone please explain in detail?
def sequence[A](aos: List[Option[A]]): Option[List[A]] =
aos.foldRight[Option[List[A]]](Some(Nil))((a,acc) => map2(a,acc)(_ :: _))

It is hard to explain with only a small piece of code, but I'll give it a try.
Explanation: That function is trying to implement a sequence operation on List[Option[A]]. This operation is really common in FP (I recommend you look at a general implementation found in cats. In general it converts type F[G[A]] to G[F[A]], in your example it specifically converts List[Option[A]] to a Option[List[A]].
Update: You have to specify Option[List[A]] to make sure the compiler will infer the correct type. Due to how ADTs are implemented in Scala, if you don't specify the return type the compiler will infer Some[List[Nothing]] as your return type.

Related

Cannot understand parameterized type

i am studying scala and have been trying to learn as much as i can. After reading the scala programming book i am reading the source code of several projects while trying some examples myself.
I am really struggling to understand what this method does. I understand that this defines a Json value such as type : value or something.
And also it expects a parametrized T that is a subtype of Product (<:), the way it uses the hashtags is completely magic to me. I cannot fathom its meaning.
def jsonFormat1[[#P1 :JF#], T <: Product :ClassManifest](construct: ([#P1#]) => T): RootJsonFormat[T] = {
val Array([#p1#]) = extractFieldNames(classManifest[T])
jsonFormat(construct, [#p1#])
}
Here is the Full Source for the trait, you might need it to fully understand
PS: This example is taken from project spray-json.

Strange type mismatch error

I have a table column errorFixed of type TableColumn[Error, Boolean] inside a TableView[Error]. My Error class has a val fixed: Boolean which I try to put into this table column.
I tried
errorFixed.cellValueFactory = features =>
ReadOnlyBooleanWrapper(features.value.fixed)
but it fails with
type mismatch;
found : scalafx.beans.property.ReadOnlyBooleanWrapper
required: scalafx.beans.value.ObservableValue[Boolean,Boolean]
which I really don't understand as ObservableValue[Boolean,Boolean] is a supertype of ReadOnlyBooleanWrapper according to the documentation.
If I cast it myself using .asInstanceOf[ObservableValue[Boolean, Boolean]] it seems to work. What is going on here?
Gist with stripped down project to reproduce
Short answer is: instead of
errorFixed.cellValueFactory = features =>
ReadOnlyBooleanWrapper(features.value.fixed)
you should use
errorFixed.cellValueFactory = features =>
ObjectProperty[Boolean](features.value.fixed)
or ReadOnlyObjectWrapper[Boolean].
A brief version of long answer: there are certain "frictions" between Scala and Java when working with primitive Java types, like boolean or int. This inconvenience shows up in property binding in ScalaFX. Not everything is inherited in an intuitive way. In this case
ReadOnlyBooleanWrapper
is a subclass of
ObservableValue[scala.Boolean, java.lang.Boolean]
but scala.Boolean is not a subclass of java.lang.Boolean which internally, in ScalaFX this leads to complications. Interesting thing is that the casting .asInstanceOf[ObservableValue[scala.Boolean, scala.Boolean]] works, though type parameters do not match at compile time.
Thanks for positing a full code example (gist) this really helps in clarifying the question.

Strange case class syntax

I've been learning Scala and decided to play with JSON parsing using json4s. I decided to use XPath syntax for deserializing and came across this strange bit of syntax I've never seen before.
val json = JsonMethods.parse("""{"meaningOfLife": 42}""")
val JInt(x) = json\"meaningOfLife"
The part confusing me is this bit right here
val JInt(x) = ...
I can't wrap my mind around what's happening there, I don't even know how to search this syntax or what it's called. Can anyone help me out? Scala is an amazing language with a lot of neat features that I'm not used to in other languages like C++ and Java.
Edit
To clarify, I'm confused because x isn't defined, but it's somehow being passed into a function or constructor then being assigned to the result of json\"meaningOfLife" which returns a JValue.
Edit 2
After some research and playing around, I figured out that this has something to do with case classes. I was able to run the following code.
case class MyCaseClass (x: Int)
val MyCaseClass(x) = new MyCaseClass(5)
println(x, x.getClass) // prints (5,int)
Which, after looking at some of the code, gives me a good understanding at what's happening.
val MyCaseClass(x) = MyCaseClass(5)
Is extracting (for lack of a better term) the Int value 5 from the instantiated MyCaseClass and storing that into x, meaning x will be of type Int.
In the code for json4s a JInt is a JValue which the \ operator returns. So the JInt(x) is taking out a BigInt (stored in the class JInt) and putting that into the value x from what I gather.
But I still have a question. What is this process called? Is there any documentation on it?
It's called "irrefutable pattern matching" and it's essentially equivalent to this bit of code:
val json = JsonMethods.parse("""{"meaningOfLife": 42}""")
val x = json match {
case JInt(xMatched) => xMatched
}
In other words, any case class or any extractor that fits the pattern of the declaration's left-hand-side can be used in this way.
Addendum:
The "irrefutable" means that a MatchError will be thrown if the pattern cannot be satisfied.

Force single argument in scala varargs

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]: _*)

Inject methods into existing classes

I want to come out a way to define a new method in some existing class in scala.
For example, I think the asInstanceOf[T] method has too long a name, I want to replace it with as[T].
A straight forward approach can be:
class WrappedAny(val a: Any) {
def as[T] = a.asInstanceOf[T]
}
implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a)
Is there a more natural way with less code?
Also, a strange thing happens when I try this:
scala> class A
defined class A
scala> implicit def toA(x: Any): A = x
toA: (x: Any)A
scala> toA(1)
And the console hang. It seems that toA(Any) should not pass the type checking phase, and it can't when it's not implicit. And putting all the code into a external source code can produce the same problem. How did this happen? Is it a bug of the compiler(version 2.8.0)?
There's nothing technically wrong with your approach to pimping Any, although I think it's generally ill-advised. Likewise, there's a reason asInstanceOf and isInstanceOf are so verbosely named; it's to discourage you from using them! There's almost certainly a better, statically type-safe way to do whatever you're trying to do.
Regarding the example which causes your console to hang: the declared type of toA is Any => A, yet you've defined its result as x, which has type Any, not A. How can this possibly compile? Well, remember that when an apparent type error occurs, the compiler looks around for any available implicit conversions to resolve the problem. In this case, it needs an implicit conversion Any => A... and finds one: toA! So the reason toA type checks is because the compiler is implicitly redefining it as:
implicit def toA(x: Any): A = toA(x)
... which of course results in infinite recursion when you try to use it.
In your second example you are passing Any to a function that must return A. However it never returns A but the same Any you passed in. The compiler then tries to apply the implicit conversion which in turn does not return an A but Any, and so on.
If you define toA as not being implicit you get:
scala> def toA(x: Any): A = x
<console>:6: error: type mismatch;
found : Any
required: A
def toA(x: Any): A = x
^
As it happens, this has been discussed on Scala lists before. The pimp my class pattern is indeed a bit verbose for what it does, and, perhaps, there might be a way to clean the syntax without introducing new keywords.
The bit about new keywords is that one of Scala goals is to make the language scalable through libraries, instead of turning the language into a giant quilt of ideas that passed someone's criteria for "useful enough to add to the language" and, at the same time, making other ideas impossible because they weren't deemed useful and/or common enough.
Anyway, nothing so far has come up, and I haven't heard that there is any work in progress towards that goal. You are welcome to join the community through its mailing lists and contribute to its development.