How does addition function parameters appeared in scala? - function

I am reading example about monad transformers in scalaz. Here is a piece of code:
scala> def myName(step: String): Reader[String, String] = Reader {step + ", I am " + _}
myName: (step: String)scalaz.Reader[String,String]
scala> def localExample: Reader[String, (String, String, String)] = for {
a <- myName("First")
b <- myName("Second") >=> Reader { _ + "dy"}
c <- myName("Third")
} yield (a, b, c)
localExample: scalaz.Reader[String,(String, String, String)]
scala> localExample("Fred")
res0: (String, String, String) = (First, I am Fred,Second, I am Freddy,Third, I am Fred)
How does it happen, that localExample can take a parameter? Oo There is not any parameters list in definition
localExample: Reader[String, (String, String, String)] just return type is specified. Also the same question about
myName function, it also has more function parameters then mentioned in its definition.

The key is in the return type that is specified, which is an instance of the Reader monad. Roughly, the reader monad is like a wrapper around a function from - in the case of myName - String to String, so it is a bit like a function defined as:
def myName(step: String): String => String
For localExample, the return type is now a "wrapper around a function from String to Triple of String" (quotes used because this is something of a simplified sense of what the Reader monad is).
In both cases, the return type is - sort of - a function that can take a (String) parameter with which to generate a final result, and it is this sort-of-a function that is taking the parameter passed to localExample in the call localExample("Fred"). Essentially like calling localExample().apply("Fred").
There is more to monads like the Reader than just the above (which I'm not sure I feel expert enough to explain properly right now), but hopefully that's enough to answer your question.

Related

Trying to use Jackson to read value to a parameterized type with scala

I'm trying to write a method that will allow Jackson ObjectMapper readValue on a json string to a parameterized object type. Something like this
case class MyObj(field1: String, field2: String)
val objectMapper: ObjectMapper = new ObjectMapper().registerModule(new DefaultScalaModule)
def fromJson[T](jsonString: String, objTyp: T): T = {
objectMapper.readValue(jsonString, classOf[T])
}
val x = fromJson("""{"field1": "something", "field2": "something"}""", MyObj)
This of course returns an error of
class type required but T found
i've looked at this issue Scala classOf for type parameter
but it doesn't seem to help. It seems like this is possible to do somehow. Looking for any help
You have to give it the actual runtime class to parse into, not just a type parameter.
One way to do it is passing the class directly:
def fromJson[T](json: String, clazz: Class[T]) = objectMapper.readValue[T](json, clazz)
val x = fromJson("""...""", classOf[MyObj])
Alternatively, you can use ClassTag, which looks a bit messier in implementation, but kinda prettier at call site:
def fromJson[T : ClassTag](json: String): T = objectMapper.readValue[T](
json,
implicitly[ClassTag[T]].runtimeClass.asInstanceOf[Class[T]]
)
val x = fromJson[MyObj]("""{"field1": "something", "field2": "something"}""")
i've looked at this issue Scala classOf for type parameter but it doesn't seem to help.
In the very first answer there it's written classTag[T].runtimeClass as a replacement of classOf[T]. This should help.
Regarding the signature
def fromJson[T](jsonString: String, objTyp: T): T
You should notice that MyObj has type MyObj.type (companion-object type), not MyObj (case-class type).
Class companion object vs. case class itself
So if you call fromJson("""...""", MyObj) then the types in these two places
def fromJson[...](jsonString: String, objTyp: ???): ???
^^^ ^^^ <--- HERE
can't be the same.
If it's enough for you to call
fromJson("""...""", classOf[MyObj])
or
fromJson[MyObj]("""...""")
(normally it should be enough) then please see #Dima's answer, you should prefer those options, they're easier.
Just in case, if you really want to call like fromJson("""...""", MyObj) then for example you can use the type class ToCompanion (this is more complicated) from
Invoke construcotr based on passed parameter
Get companion object of class by given generic type Scala (answer)
// ToCompanion should be defined in a different subproject
def fromJson[C, T](jsonString: String, objTyp: C)(implicit
toCompanion: ToCompanion.Aux[C, T],
classTag: ClassTag[T]
): T =
objectMapper.readValue(jsonString, classTag.runtimeClass.asInstanceOf[Class[T]])
val x = fromJson("""{"field1": "something", "field2": "something"}""", MyObj)
// MyObj(something,something)

Need to pass pair as separate components to Json.obj

I'm using Scala Play to process some JSON. I tried this:
val pair = ("foo", "bar")
val json = Json.obj(pair)
This gives me
type mismatch; found : (String, String) required: (String, play.api.libs.json.Json.JsValueWrapper)
Okay, fair enough. But if I do this instead:
val json = Json.obj(pair._1 -> pair._2)
Everything is fine. But I thought x -> y was just syntactic sugar for (x, y). It looks as if the latter expression is just constructing a new pair that's identical to the original and passing it to Json.obj, but something is clearly different between the two cases. What's going on?
The method obj takes tuples of type (String, JsValue)*. When you passed a tuple of (String, String), the compiler complained of type mismatch. (String, String) is not same as (String, JsValue)
Now, from docs
Most values don’t need to be explicitly wrapped by JsValue classes,
the factory methods use implicit conversion
The Play JSON API provides implicit Writes for most basic types,
such as Int, Double, String, and Boolean
When you passed String -> String, compiler has two options to implicitly convert String -> String to a tuple (String, String) or from String -> String to String -> JsValue to a tuple (String, JsValue). The second option matches the type required for the obj method and compiler follows that way to get a error free code.

Why are Scala class methods not first-class citizens?

I've just started Scala and am tinkering in worksheets. For example:
def merp(str: String) : String = s"Merrrrrrrp $str"
val merp2 = (str: String) => s"Merrrrrrrp $str"
val merp3 = (str: String) => merp(str)
val merp4 = merp _
merp("rjkghleghe")
merp4("rjkghleghe")
And the corresponding worksheet results:
merp: merp[](val str: String) => String
merp2: String => String = <function1>
merp3: String => String = <function1>
merp4: String => String = <function1>
res0: String = Merrrrrrrp rjkghleghe
res1: String = Merrrrrrrp rjkghleghe
Saying, for example, val merp5 = merp produces an error, because apparently methods cannot be values the way functions can. But I can still pass methods as arguments. I demonstrate this in the following code snippet, adapted from a similar SO question:
def intCombiner(a: Int, b: Int) : String = s"herrrrrrp $a derrrrrrp $b"
def etaAbstractor[A, B](combineFoo: (A, B) ⇒ String, a: A, b: B) = combineFoo(a, b)
etaAbstractor(intCombiner, 15, 16)
worksheet result:
intCombiner: intCombiner[](val a: Int,val b: Int) => String
etaAbstractor: etaAbstractor[A,B](val combineFoo: (A, B) => String,val a: A,val b: B) => String
res10: String = herrrrrrp 15 derrrrrrp 16
Is methods-not-being-first-class a limitation, perhaps imposed by Scala's JVM interaction, or is it a decision in the language's design?
Why do I need to roll my own eta abstractions, as in merp3?
Is merp4 also an eta abstraction, or is it something sneakily similar?
Why does my etaAbstractor work? Is Scala quietly replacing intCombiner with intCombiner _?
Theoretical, computer sciencey answers are welcome, as are pointers to any relevant points in the language specification. Thanks!
Disclaimer: I'm not a computer scientist, but I will try to guess:
Method is a part of an object and doesn't exist outside of it. You can't pass method alone. Closure is another (equivalent?) way of encapsulating state, by converting an object method to a standalone function (which is by the way just another object with apply() method in Scala) you are creating a closure. This process is known as eta-expansion. §3.3.1, §6.26.5
You don't have to. You can also write val merp3 : (String => String) = merp. §6.26.5
Yes, merp4 is eta-expansion too. §6.7
§6.26.2
The reason it works with etaAbstractor is that the compiler can infer that a function (not a function invocation) is required.
If I had to guess why the underscore is required where a function type cannot be inferred, I'd think that it's to improve error reporting of a common class of errors (getting functions where invocations are intended). But again, that's just a guess.
In the JVM, a method is not an object, whereas a first-class function must be one. So the method must be boxed into an object to convert it to a function.

Deciphering Scala code... JSON / Play framework / combinator / functional / tricks / OWrites

I'm trying to understand every piece of the implementation of class OWritesOps explained here: http://kailuowang.blogspot.mx/2013/11/addremove-fields-to-plays-default-case.html
The way scala / play doc is structured doesn't really help (in this area Java(doc) beats Scala(doc) hands down).
Let's start with: addField:
def addField[T: Writes](fieldName: String, field: A => T): OWrites[A] =
(writes ~ (__ \ fieldName).write[T])((a: A) => (a, field(a)))
I could only guess that the ~ is an equivalent of "and" (I gather it from here: http://mandubian.com/2012/10/01/unveiling-play-2-dot-1-json-api-part2-writes-format-combinators/ )
Alright, so let's just take it this way: (writes ~ (__ \ fieldName).write[T]) create a new instance of Writes (combo).
What about (__ \ fieldName) ? After a lot of digging Play Doc, I came to a (shaky) conclusion that it produces an instance of JsPath? How did I arrive to that conclusion? It's for that .write[T] that follows; JsPath has that method.
Beside, I read somewhere that __ is a shortcut for JsPath (I forgot where, I guess it's in Play Doc as well, but using Scala doc it's almost impossible to find my way back to that page).
Ok..., so (writes ~ (__ \ fieldName).write[T]) produces an instance of OWrites. Next: what's this?: ((a: A) => (a, field(a)))
Oh..., it's for the apply the parameter to the "apply" method of OWrites; it takes an lambda function with the following signature ((A) => JsObject)
Ok...., so.... (a, field(a)) is supposed to create an instance of JsObject. So, I opened the play doc, JsObject. Hmm..., I guess it's this constructor (?): JsObject(fields: Seq[(String, JsValue)]) .... But,... I really doubt it.... I'm lost here.
Anyway, let's see an example how it is used:
val customWrites: Writes[Person] = Json.Writes[Person]. addField("isAdult", _.isAdult)
So..., _.isAdult is supposed to map to a block with the following signature: A => T ... But..., if that's really the case, I was expecting {x => x.isAdult} .... so I guess _.isAdult is a syntactic-sugar provided by Scala (?).
So... back to the definition of addField: field(a) executes the block "_.isAdult". I can infer here that a is an instance of Person then.
Can you help me decipher all this?
Scala is cool, but it's doc system (still) sucks :(
Can you help me decipher all this?
I could only guess that the ~ is an equivalent of "and"
~ is the name of a method invoked on the instance of OWrites. writes ~ (__ \ fieldName).write[T]) is the same as writes.~((__ \ fieldName).write[T])). Note the brackets around the argument of ~.
There are two things relevant to this equivalent form:
In Scala, any method with one argument can be written using infix notation. For example, if you have an instance list: java.util.ArrayList[Int], you could write list add 5.
While a method name need not be alphanumeric (as in Java), not all operators have the same precedence. For example, 1 + 5 * 2 translates to 1.+(5.*(2)) and not to 1.+(5).*(2). Here's a summary of operator precedence in Scala.
However, OWrites has no method called ~ in its interface. If you import play.api.libs.functional.syntax._, there's an implicit conversion
implicit def toFunctionalBuilderOps[M[_], A](a: M[A])(implicit fcb: FunctionalCanBuild[M]) = new FunctionalBuilderOps[M, A](a)(fcb)
and FunctionalBuilderOps defines the method
def ~[B](mb: M[B]): FunctionalBuilder[M]#CanBuild2[A, B] = {
val b = new FunctionalBuilder(fcb)
new b.CanBuild2[A, B](ma, mb)
}
and an alias for it: def and[B](mb: M[B]): FunctionalBuilder[M]#CanBuild2[A, B] = this.~(mb)
What about (__ \ fieldName) ?
The package play.api.libs.json defines a value val __ = JsPath, so the double underscores are just an alias for the singleton object JsPath. The singleton object JsPath is not to be confused with the equally-named class. This construct is called a companion object in Scala. While Java puts static members next to the regular members in a class, Scala puts them inside the companion object.
Apparently, the object JsPath is at the same time the companion object of the case class JsPath and an instance of JsPath(List.empty).
fieldName is of type String and JsPath defines a method
def \(child: String) = JsPath(path :+ KeyPathNode(child))
which is equivalent to
def \(child: String) = JsPath.apply(path :+ KeyPathNode(child))
The default apply method of a case class' companion object creates a new instance, so this is equivalent to
def \(child: String) = new JsPath(path :+ KeyPathNode(child))
As our singleton object __ is an instance of JsPath with the empty list for path, this returns us a new JsPath(KeyPathNode(child)), where child == fieldName
what's this?: ((a: A) => (a, field(a)))
It's a function taking an instance of A. The function maps the argument a to the tuple (a, field(a), where field is a function provided as argument to your method addField. It has the signature field: A => T, so it is a function that takes an instance of A and returns an instance of T.
This may be a bit confusing, so let me give you an example function that does not operate on generics. Say you want to define a function f that squares an integer number. For example, f(1) should be 1, f(3) should be 9. As it takes an integer and returns an integer, its signature is f: Int => Int. It's implementation is f = (x: Int) => x * x.
Oh..., it's for the apply the parameter to the "apply" method of OWrites; it takes an lambda function with the following signature ((A) => JsObject)
Actually, this is not correct - the signatures do not match. The given lambda function is of type A => (A, T). Also, as pointed out in the first part of the answer, the method ~ returns an instance of FunctionalBuilder#CanBuild2. Unfortunatly, I am lost on what the called apply-method does, because it is highly generic and uses implicit arguments of a generic type.
so I guess _.isAdult is a syntactic-sugar provided by Scala (?).
Yes, the underscore in lambda functions is syntactic sugar for capturing the arguments. For example, _ + _ is syntactic sugar for (x, y) => x + y, meaning the following two values are equivalent:
val f: (Int, Int) => Int = (x, y) => x + y
val g: (Int, Int) => Int = _ + _
So _.isAdult really just translates to {x => x.isAdult} and in the example, x: Person.
Update
The idea behind this write builder seems to be to provide means of defining a mapping from one of your Scala classes to JSON. Let's take a look again at the case class Person(name: String, age: Int). Now, let's assume we have an instance of Person:
val odersky = Person("Martin Odersky", 56)
and want to serialize the instance to the following JSON:
{
"name": "Martin Odersky",
"age": 56
}
The key is always a string, but the value can be of a different type. So, basically, the serialization is a function taking a Person and returning a tuple of key-value pairs where the value is always a string, i.e., Person => ((String, String), (String, Int)). Or, in the general case where we do not know what we are going to serialize, simply that it has two fields, it is A => ((String, B), (String, C)) for arbitrary types A, B, and C.
This is what CanBuild2 emulates - the 2 standing for the number of members to serialize. There's also a CanBuild3, CanBuild4 and so on.
We can instantiate a CanBuild2 that is appropriate to our example, by calling
val serializer = (__ \ "name").write[String] ~ (__ \ "age").write[Int]
Here, the type of serializer is FunctionalBuilder[OWrites]#CanBuild2[String, Int]
Now, the apply method of CanBuild2 can be used to generate an instance of the first generic argument - OWrites. The argument to the apply method is a function that maps an instance of our type to serialize (here Person) to a tuple of the desired value types, here String and Int (representing name and age).
val personWriter: OWrites[Person] = serializer((p: Person) => (p.name, p.age))
This writer can now be used to generate a JSON string from any instance of Person. So we can pass our person and get the desired output:
println(toJson(odersky)(personWriter))

Scala type parameters by declaring the type inside the function

I'm just starting to learn Scala, coming from a Java background. I have been trying to understand type parameters in functions and inference of types. This is a standard example in the Scala docs:
class Decorator(left: String, right: String) {
def layout[A](x: A) = left + x.toString() + right
}
object FunTest extends Application {
def apply(f: Int => String, v: Int) = f(v)
val decorator = new Decorator("[", "]")
println(apply(decorator.layout, 7))
}
If I try to apply a type parameter to the apply function and keep v a strong type, a type mismatch occurs. Why doesn't the type get inferred here?
def apply[B](f: B => String, v: String) = f(v) //Type mismatch
def apply[B](f: B => String, v: B) = f(v) //Works fine
Thanks
Let's take a look at apply without it's body:
def apply[B](f: B => String, v: String)
That reads "apply is a function (method) parameterized on a type B, that takes a function from B to String, and a String".
Think of B as a type variable; it will need to be instantiated at some point. That point is not the declaration of apply. It is when apply is, well, applied to ;-)
By this contract, usage like this must be allowed:
def g(i: Int): String = "i is " + i
apply(g, "foo") // Here the type variable `B` is "instantiated" to the type Int,
But given that you have a body like f(v), just substituting, we see the contradiction:
Substitute
f(v)
With
g("foo") // can't compile; g takes a B, which is an Int