Scala Syntax: Syntactic sugar for converting a Function0 into function1? - scala

Sorry for the nebulous title, I had a hard time to to formulate what I mean. For that reason, lets directly dive into the code:
def bar(b: Int => String) = b(23)
def foo(b: => String) = bar(_ => b)
foo("foo" + "bar")
I found a similar code in the play framework and was wondering what actually happens with that code. I tinkered a bit and figured that bar(_ => b) will just create a function1 with the required argument type (given by bars signature) and uses the given function0 to generate the return value, ignoring the actual parameter of the function1.
However, this is just me trying to figure out what happens, a more definitive answer would be way better for my understanding - and besides that I might be completely wrong.

You're sort of right, except that => String is not a Function0 - () => String is.
=> String is a call-by-name string. It'll be evaluated when it's referred to.
def foo(b: String) = bar(_ => b) would also get the job done, with the exception that b would be evaluated eagerly.

Related

What foreach(_ => ()) this mean in Scala?

I found this foreach(_ => ()) in a code that uses Monix stream, I am not understanding the meaning. Can someone explain me this?
monix_concurrent_subject.foreach(_ => ())
As urmaul explained in the comments, it depends:
If the datastructure is eager, it does nothing. Examples are List, Option etc.
If the datastructure is lazy, it initialises its content. An example is a Stream.
Also as foreach returns nothing, it implies that somewhere will be a Side-Effect in the code before the foreach.
If you check the API (ConcurrentSubject.html#foreach) it states:
foreachL(cb: (O) ⇒ Unit): Task[Unit]
Creates a new Task that will consume the source observable, executing the given callback for each element.
() represents the value in the type of Unit. It is perhaps unusual-looking but it is a true value nevertheless, akin to how 42 represents a value in the type of Int. For example, we can write
val u: Unit = ()
similarly to
val i: Int = 42
() does not carry much meaning beyond indicating some side-effect occurred in a function.
Now consider the following function of type Int => Unit
(x: Int) => ()
Note how we do nothing with parameter x on the right of =>, that is, it is not used at all. We can express this meaning explicitly using an underscore _
(_: Int) => ()
or even simply
_ => ()
if type inference can figure out the types. Applying an argument to this function
((x: Int) => ())(42)
results in nothing interesting. So putting these pieces together we get perhaps the following interpretation of meaning of _ => ():
do nothing effect
trivial effect
no operation effect
effect without effect
However despite _ => () having no direct effect it may have some indirect effect when passed to foreach as explained by pme.
Regarding
monix_concurrent_subject.foreach(_ => ())
it seems to me here foreach(_ => ()) is more of a hack to achieve something for which monix_concurrent_subject should really provide a proper method.

Why does creating a map function whose parameter is of type `Nothing => U` appear to work?

I'm writing Scala code that uses an API where calls to the API can either succeed, fail, or return an exception. I'm trying to make an ApiCallResult monad to represent this, and I'm trying to make use of the Nothing type so that the failure and exception cases can be treated as a subtype of any ApiCallResult type, similar to None or Nil. What I have so far appears to work, but my use of Nothing in the map and flatMap functions has me confused. Here's a simplified example of what I have with just the map implementation:
sealed trait ApiCallResult[+T] {
def map[U]( f: T => U ): ApiCallResult[U]
}
case class ResponseException(exception: APICallExceptionReturn) extends ApiCallResult[Nothing] {
override def map[U]( f: Nothing => U ) = this
}
case object ResponseFailure extends ApiCallResult[Nothing] {
override def map[U]( f: Nothing => U ) = ResponseFailure
}
case class ResponseSuccess[T](payload: T) extends ApiCallResult[T] {
override def map[U]( f: T => U ) = ResponseSuccess( f(payload) )
}
val s: ApiCallResult[String] = ResponseSuccess("foo")
s.map( _.size ) // evaluates to ResponseSuccess(3)
val t: ApiCallResult[String] = ResponseFailure
t.map( _.size ) // evaluates to ResponseFailure
So it appears to work the way I intended with map operating on successful results but passing failures and exceptions along unchanged. However using Nothing as the type of an input parameter makes no sense to me since there is no instance of the Nothing type. The _.size function in the example has type String => Int, how can that be safely passed to something that expects Nothing => U? What's really going on here?
I also notice that the Scala standard library avoids this issue when implementing None by letting it inherit the map function from Option. This only furthers my sense that I'm somehow doing something horribly wrong.
Three things are aligning to make this happen, all having to do with covariance and contravariance in the face of a bottom type:
Nothing is the bottom type for all types, e.g. every type is its super.
The type signature of Function1[-T, +R], meaning it accepts any type which is a super of T and returns any type for which R is a super.
The type ApiCallResult[+R] means any type U for which R is a super of U is valid.
So any type is a super of Nothing means both any argument type is valid and the fact that you return something typed around Nothing is a valid return type.
I suggest that you don't need to distinguish failures and exceptions most of the time.
type ApiCallResult[+T] = Try[T]
case class ApiFailure() extends Throwable
val s: ApiCallResult[String] = Success("this is a string")
s.map(_.size)
val t: ApiCallResult[String] = Failure(new ApiFailure)
t.map(_.size)
To pick up the failure, use a match to select the result:
t match {
case Success(s) =>
case Failure(af: ApiFailure) =>
case Failure(x) =>
}

Call by value with values interpreted as zero-argument functions vs call by name

In this comment, #Ben suggested that call by name is equivalent to call by value where values are zero-argument functions. If I understood correctly,
def callByName(x: => Int) = {
// some code
}
callByName(something())
is equivalent to
def callByValue(x: () => Int) = {
// same code as above, but all occurrences of x replaced with x()
}
callByValue(()=>something())
(Edit: I fixed mistake in signature as pointed out by #MichaelZajac, #LukaJacobowitz: originally, it said callByValue(x: Int).)
In other words, the whole "call by name" concept is just syntactic sugar: everything it does can be achieved (with a few extra keystrokes) using "call by value". If true, it makes it very easy to understand call by name; in fact, I've used this technique in python (python has first-class functions).
However, further down in the comments, the discussion became somewhat more confusing, and I was left with the feeling that it's not quite so simple.
So is there something more substantive to "call by name"? Or is it just an automatic creation of zero-argument functions by the compiler?
I'm assuming you meant your callByValue function to take a () => Int instead of just an Int as otherwise it wouldn't make a lot of sense.
It's pretty much exactly what you think. The compiler generates a Function0 instance. You can see this pretty nicely when you decompile Scala code with Javap.
Another thing of note is, that the generated Function0 will be reevaluated every time you use the by-name parameter inside your function, so if you only want it to be computed once you'll want to do something like this:
def callByName(x: => Int) = {
val a = x
// do something with a here
}
Here is some more information on the whole concept.
Also you can see how Scala compiles by-name parameters quite neatly in this question:
def getX[T <: X](constr: ⇒ T): Unit = {
constr
}
decompiled in Java is equivalent to:
public <T extends X> void getX(Function0<T> constr) {
constr.apply();
}
Yes, but your example isn't quite right. The signature of callByValue, as written in your question, will evaluate x before callByValue is invoked.
The following would be roughly equivalent to a call-by-name:
def callByValue(x: () => Int) = {
// same code as above, but all occurrences of x replaced with x()
}
The distinction is important, because your version of callByValue would only accept Ints, not functions that return Ints. It also wouldn't compile if you followed the procedure of replacing x with x().
But yes, a call-by-name parameter of => A is roughly equivalent to () => A, except that the former is simply more convenient to use. I say roughly because they are different types, and their applications are slightly different. You can specify () => A to be the type of something, but not => A. And of course with x: () => A, you must manually call x() instead of x.

Chaining futures and options idiomatically

def foo(user, id): Future[Option[Bar]] =
bar(user, id).map(_.map(_.address.flatMap(_.street)))
.flatMap {
case Some(street) =>
baz(user, street).flatMap(_ => get(id))
case None => successful(None)
}
Function bar returns an Option[UserInfo], which I then map to a UserInfo. Address is also an Option so I flatMap that to have access to street. Then simply if there exists a street I want to call baz, if not then None. Ignore the business logic, it's made up for the example.
There's a problem with the code here as it won't compile.
Some(street) is an Option, since the flatMap on line 3 is being called on the result of the mapping on the first _, instead of _.address.
Whilst I could get this to work with some parenthesis juggling and so on, this code is starting to get hard to read and reason about.
Are for-comprehensions the answer?
P.S: There might be some type-information missing in this example so please ask and I will elaborate.
EDIT:
case class UserInfo(id: UserId, address: Option[Address])
case class Address(street: Option[List[Street]], state: Option[State])
If I understood method signatures right:
def bar(user, id): Option[UserInfo]
def baz(user, List[Street]): Future[BarId]
def get(id): Option[Bar]
You can implement your method something like this:
val streetsOpt: Option[List[Street]] = bar(user, id).flatMap(_.flatMap(_.address.flatMap(_.street)))
streetsOpt.flatMap(streets => {
baz(user, streets).map(_ => get(id))
}).getOrElse(successful(None)))
Just quickly looking at this, within this line:
baz(user, street).flatMap(_ => get(id))
I don't think that the last flatMap won't work properly because you seem to be passing in a function which is of a type something like:
f: => A
i.e. extracting the underlying value from some context, whereas flatMap expects you to unpack this value and then wrap in a new context, and so has type:
f: A => M[B]
When you are making the call to
get(id)
Shouldn't this be being applied to a map method instead, which expects a function of type:
f: A => B
There are a couple of ways of dealing with nested contexts like this. I gave a talk about three that I know: monad transformers (explicit, more "standard", but a bit more verbose), Kleisli (very elegant, if you're willing to write in pointfree style), or my scalaz-transfigure library (a bit immature, a bit less explicit, but very concise).

def fn[String] seems to break Scala / java.lang.String compatibility

Hello there Stack Overflow,
I hope you'll help me with my very first question here :)
So I'm having a problem with Scala type inference. Here is the code:
object Problem {
def ok(fn: (String) => Unit) = fn("")
// type mismatch; found: java.lang.String("") required: String
def fail[String](fn: (String) => Unit) = fn("")
}
What kind of String does Scala expect here?
Note that this is a minimal example to explain my problem. The original issue appeared when I tried to implement a more complex interface (Play's Iteratee, to be precise), so, no, leaving out the [String] is not an option. (If anyone thinks that the actual code would help, I'll provide it.)
I tried def fail[java.lang.String] ... but then it says expected ], found ..
I did read Scala String vs java.lang.String - type inference which gives a good explanation on java.lang.String vs. scala.Predef.String, but I still could not come up with a solution for my specific problem.
Any ideas?
EDIT: So here is the original attempt how I tried to implement http://www.playframework.org/documentation/api/2.0/scala/play/api/libs/iteratee/Iteratee.html only that I wrote String instead of T. (With T it compiles, and it makes sense!) My fail; obviously I was a bit overwhelmed by all the type parameters:
val stream = WS.url("url").get({ headers =>
(new Iteratee[Array[Byte], String] {
def fold[T](done: (String, Input[Array[Byte]]) => Promise[T],
cont: (Input[Array[Byte]] => Iteratee[Array[Byte], String]) => Promise[T],
error: (String, Input[Array[Byte]]) => Promise[T]): Promise[T] =
{
done("something", Input.Empty)
}
})
})
Regards,
Hendrik
When you write:
def fail[String](fn: (String) => Unit) = fn("")
The type parameter between square brackets String is just an arbitrary name that, in your case, will hide scala or java string. It is fully equivalent to:
def fail[T](fn: (T) => Unit) = fn("")
If you want to constrain the type to string, you just have to write:
def fail(fn: (String) => Unit) = fn("")
And it will work for scala and java strings (since they are the same).
This problem has nothing to do with Java vs Scala strings.
In the line def fail[String](fn: (String) => Unit) = fn("") you're definining a completely new type parameter and naming it String. This shadows the general definition.
A type paramter is needed if you intend to abstract over the type. You are not doing this in the fail example, and this should be dropped.
If you are overriding something that uses a type parameter, then you should specify this at the class level:
class A extends B[String]
Looking at the code for Iteratee, I'll guess you're trying to implement fold with its various done, cont and error functions. Fold only has one type paramter, which is used in the return type, so I'm not sure where this can come from. The input type parameters are specified on the class, so if you extend Iteratee[String, Unit] these should be provided.