Composing curried functions - scala

I'm in the following situation. I would like a function to only be able to run in a given context. At the same time I would love to be able to compose these functions using the andThen syntax (It would just look much better in this case).
So here is a small example for a worksheet. I would love to be able to do it the second way.
implicit val iInt: Int = 2
def a(a: String)(implicit ctx: Int): String = a
def b(b: String)(implicit ctx: Int): String = b
val works = b(a("foo"))
val fails = a("foo") andThen b
The general question would probably be. How does one compose curried functions? But if somebody can meet the requirements described in the first paragraph I would also be interested.

This line works as you want with your definitions of a and b:
val worksToo = (a _ andThen b) ("foo")
a and b are transformed to functions (because there are not), then chained.

Related

Scala3 "as" and "with" keywords used with "given"

Currently learning about Scala 3 implicits but I'm having a hard time grasping what the ​as and with keywords do in a definition like this:
given listOrdering[A](using ord: Ordering[A]) as Ordering[List[A]] with
​def compare(a: List[A], b: List[A]) = ...
I tried googeling around but didn't really find any good explanation. I've checked the Scala 3 reference guide, but the only thing I've found for as is that it is a "soft modifier" but that doesn't really help me understand what it does... I'm guessing that as in the code above is somehow used for clarifying that listOrdering[A] is an Ordering[List[A]] (like there's some kind of typing or type casting going on?), but it would be great to find the true meaning behind it.
As for with, I've only used it in Scala 2 to inherit multiple traits (class A extends B with C with D) but in the code above, it seems to be used in a different way...
Any explanation or pointing me in the right direction where to look documentation-wise is much appreciated!
Also, how would the code above look if written in Scala 2? Maybe that would help me figure out what's going on...
The as-keyword seems to be some artifact from earlier Dotty versions; It's not used in Scala 3. The currently valid syntax would be:
given listOrdering[A](using ord: Ordering[A]): Ordering[List[A]] with
​ def compare(a: List[A], b: List[A]) = ???
The Scala Book gives the following rationale for the usage of with keyword in given-declarations:
Because it is common to define an anonymous instance of a trait or class to the right of the equals sign when declaring an alias given, Scala offers a shorthand syntax that replaces the equals sign and the "new ClassName" portion of the alias given with just the keyword with.
i.e.
given foobar[X, Y, Z]: ClassName[X, Y, Z] = new ClassName[X, Y, Z]:
def doSomething(x: X, y: Y): Z = ???
becomes
given foobar[X, Y, Z]: ClassName[X, Y, Z] with
def doSomething(x: X, y: Y): Z = ???
The choice of the with keyword seems of no particular importance: it's simply some keyword that was already reserved, and that sounded more or less natural in this context. I guess that it's supposed to sound somewhat similar to the natural language phrases like
"... given a monoid structure on integers with a • b = a * b and e = 1 ..."
This usage of with is specific to given-declarations, and does not generalize to any other contexts. The language reference shows that the with-keyword appears as a terminal symbol on the right hand side of the StructuralInstance production rule, i.e. this syntactic construct cannot be broken down into smaller constituent pieces that would still have the with keyword.
I believe that understanding the forces that shape the syntax is much more important than the actual syntax itself, so I'll instead describe how it arises from ordinary method definitions.
Step 0: Assume that we need instances of some typeclass Foo
Let's start with the assumption that we have recognized some common pattern, and named it Foo. Something like this:
trait Foo[X]:
def bar: X
def foo(a: X, b: X): X
Step 1: Create instances of Foo where we need them.
Now, assuming that we have some method f that requires a Foo[Int]...
def f[A](xs: List[A])(foo: Foo[A]): A = xs.foldLeft(foo.bar)(foo.foo)
... we could write down an instance of Foo every time we need it:
f(List(List(1, 2), List(3, 4)))(new Foo[List[Int]] {
def foo(a: List[Int], b: List[Int]) = a ++ b
def bar: List[Int] = Nil
})
Acting force: Need for instances of Foo
Solution: Defining instances of Foo exactly where we need them
Step 2: Methods
Writing down the methods foo and bar on every invocation of f will very quickly become very boring and repetitive, so let's at least extract it into a method:
def listFoo[A]: Foo[List[A]] = new Foo[List[A]] {
def foo(a: List[A], b: List[A]): List[A] = a ++ b
def bar: List[A] = Nil
}
Now we don't have to redefine foo and bar every time we need to invoke f; Instead, we can simply invoke listFoo:
f(List(List(1, 2), List(3, 4)))(listFoo[Int])
Acting force: We don't want to write down implementations of Foo repeatedly
Solution: extract the implementation into a helper method
Step 3: using
In situations where there is basically just one canonical Foo[A] for every A, passing arguments such as listFoo[Int] explicitly quickly becomes tiresome too, so instead, we declare listFoo to be a given, and make the foo-parameter of f implicit by adding using:
def f[A](xs: List[A])(using foo: Foo[A]): A = xs.foldLeft(foo.bar)(foo.foo)
given listFoo[A]: Foo[List[A]] = new Foo[List[A]] {
def foo(a: List[A], b: List[A]): List[A] = a ++ b
def bar: List[A] = Nil
}
Now we don't have to invoke listFoo every time we call f, because instances of Foo are generated automatically:
f(List(List(1, 2), List(3, 4)))
Acting force: Repeatedly supplying obvious canonical arguments is tiresome
Solution: make them implicit, let the compiler find the right instances automatically
Step 4: Deduplicate type declarations
The given listFoo[A]: Foo[List[A]] = new Foo[List[A]] { looks kinda silly, because we have to specify the Foo[List[A]]-part twice. Instead, we can use with:
given listFoo[A]: Foo[List[A]] with
def foo(a: List[A], b: List[A]): List[A] = a ++ b
def bar: List[A] = Nil
Now, there is at least no duplication in the type.
Acting force: The syntax given xyz: SomeTrait = new SomeTrait { } is noisy, and contains duplicated parts
Solution: Use with-syntax, avoid duplication
Step 5: irrelevant names
Since listFoo is invoked by the compiler automatically, we don't really need the name, because we never use it anyway. The compiler can generate some synthetic name itself:
given [A]: Foo[List[A]] with
def foo(a: List[A], b: List[A]): List[A] = a ++ b
def bar: List[A] = Nil
Acting force: specifying irrelevant names that aren't used by humans anyway is tiresome
Solution: omit the name of the givens where they aren't needed.
All together
In the end of the process, our example is transformed into something like
trait Foo[X]:
def foo(a: X, b: X): X
def bar: X
def f[A](xs: List[A])(using foo: Foo[A]): A = xs.foldLeft(foo.bar)(foo.foo)
given [A]: Foo[List[A]] with
def foo(a: List[A], b: List[A]): List[A] = a ++ b
def bar: List[A] = Nil
f(List(List(1, 2), List(3, 4)))
There is no repetitive definition of foo/bar methods for Lists.
There is no need to pass the givens explicitly, the compiler does this for us.
There is no duplicated type in the given definition
There is no need to invent irrelevant names for methods that are not intended for humans.

Scala - implicit conversion from T to Some[T]

Consider this piece of code
def foo(b: Int) = ???
val a = 3
foo(a)
It works fine of course, but let's say that later I decided that foo should support an empty input, so I change it's signature to
def foo(b: Option[Int]) = ???
Now foo(a) won't compile, because a isn't an Option[Int], it's an Int. So you have to say a = Some(3) or foo(Some(a)), which seems redundant to me.
My question is, why doesn't the language have an implicit conversion from T to Some[T] (and vice versa)?
Is it a good idea to implement one yourself?

In Scala, what is the difference between fun _ and fun as parameters

Lets say we have a function def fun(x: X): X => Y and we pass this function as a parameter to another function using fun _ instead of just fun. I understand that fun _ is actually a function value, while fun refers to a function definition.
For example let:
val a = List(1,2,3,4)
def fun(x: Int) = {println(x); x + 1}
Then Running:
//This line works
a.map(fun _)
//This one also works, even though "fun" is not a function value
a.map(fun)
They have the same output:
1
2
3
4
resX: List[Int] = List(2, 3, 4, 5)
For the most part they seem to work the same, are there any examples in which the function value is not equivalent to the function definition?
In the signature of map, you can see that it's expecting a
"function" to apply to each element
But in your code, fun is a regular method in a class. So when you do:
a.map(fun _)
you are explicitly asking for eta-expansion. When you do:
a.map(fun)
you are implicitly asking for eta-expansion.
Because fun is a "method", and is being used in a place where a Function type is expected, it's automagically converted to that type. Basically to something like:
new Function1[Int, Int] {
def apply(x: Int): Int = fun(x)
}
This transformation converting the name fun to a Function is called eta-expansion. See documentation for details.
Unfortunately, there are various ways of doing what you're doing - a.map(fun), a.map(fun _), a.map(fun(_)) and a.map(x => fun(x)). This is one of those frequent scenarios in Scala where you can explicitly do something yourself, or explicitly ask the compiler to do it for you, or just let the compiler do it implicitly. They can have different behaviors because of implicits and it can be a major source of confusion. Also, _ is heavily overloaded in the language, only adding to the confusion. So I use implicit behavior sparingly in general.
As others have pointed out in the comments, you need to use the fun _ syntax (which performs an eta expansion) when you need a value (methods have no value by themselves). Within the context of a map (or other functional contexts) an eta expansion is performed on the method implicitly. There are some cases where the eta expansion must be triggered manually.
As a concrete example of where an explicit eta expansion is needed, consider this valid snippet:
def f1(x: Int): Int = 2*x
def f2(x: Int): Int = 3*x
val fList1 = List(f1 _, f2 _)
fList1.map(_(2)) // List(4, 6)
as opposed to this invalid snippet.
val fList2 = List(f1, f2)

Function Literal referencing by val and def

I'm trying to understand the crucial difference between these two approaches of referencing / defining Function Literal (reference to anonymous function):
By val
scala> val v2 = new Function[Int, Int] {
| def apply(a: Int): Int = a + 1
| }
v2: Int => Int = <function1>
And by def
scala> def f2 = new Function[Int, Int] {
| def apply(a: Int): Int = a + 1
| }
f2: Int => Int
It seems that it pretty much the same in terms of use. I either can pass v2 or f2 to the function that accepts (Int) => Int as an argument. Passing arguments to its..
I guess or the case of v2 it creates an Function1 object that refers to the Function1 object.. like a proxy?
Ok.. My question is: what is advantage and disadvantages of 1th and 2nd approach?
And of it is defined by def, is it still Function Literal?
First of all, neither of your examples are actually function literals—you're creating a Function instance in the plain old sugar-free way, and in fact you could use this approach (new Function { ... }) to create an instance of scala.Function from Java code.
The following are both function literals, and are exactly equivalent to your definitions:
val v2 = (a: Int) => a + 1
def f2 = (a: Int) => a + 1
The only real difference here is that the val will create a single instance once and for all, no matter how many times you use v2 (and even if you never use it), while the def will create a new instance every time (or not at all, if you never use it). So you'll generally want to go with a val.
There are cases, however, where you need to use def. Consider the following:
def myIdentity[A] = (a: A) => a
There's no way we could write this as a val, since Scala doesn't have polymorphic functions in this sense (for any instance of Function[A, B], A and B have to be concrete types). But we can define a polymorphic method that returns a function, and when we write e.g. myIndentity(1), the A will be inferred to be Int, and we'll create (and apply) a Function[Int, Int] exactly as you'd expect.

Coding with Scala implicits in style

Are there any style guides that describe how to write code using Scala implicits?
Implicits are really powerful, and therefore can be easily abused. Are there some general guidelines that say when implicits are appropriate and when using them obscures code?
I don't think there is a community-wide style yet. I've seen lots of conventions. I'll describe mine, and explain why I use it.
Naming
I call my implicit conversions one of
implicit def whatwehave_to_whatwegenerate
implicit def whatwehave_whatitcando
implicit def whatwecandowith_whatwehave
I don't expect these to be used explicitly, so I tend towards rather long names. Unfortunately, there are numbers in class names often enough so the whatwehave2whatwegenerate convention gets confusing. For example: tuple22myclass--is that Tuple2 or Tuple22 you're talking about?
If the implicit conversion is defined away from both the argument and result of the conversion, I always use the x_to_y notation for maximum clarity. Otherwise, I view the name more as a comment. So, for instance, in
class FoldingPair[A,B](t2: (A,B)) {
def fold[Z](f: (A,B) => Z) = f(t2._1, t2._2)
}
implicit def pair_is_foldable[A,B](t2: (A,B)) = new FoldingPair(t2)
I use both the class name and the implicit as a sort of a comment about what the point of the code is--namely to add a fold method to pairs (i.e. Tuple2).
Usage
Pimp-My-Library
I use implicit conversions the most for pimp-my-library style constructions. I do this all over the place where it adds missing functionality or makes the resulting code look cleaner.
val v = Vector(Vector("This","is","2D" ...
val w = v.updated(2, v(2).updated(5, "Hi")) // Messy!
val w = change(v)(2,5)("Hi") // Okay, better for a few uses
val w = v change (2,5) -> "Hi" // Arguably clearer, and...
val w = v change ((2,5) -> "Hi", (2,6) -> "!")) // extends naturally to this!
Now, there is a performance penalty to pay for implicit conversions, so I don't write code in hotspots this way. But otherwise, I am very likely to use a pimp-my-library pattern instead of a def once I go above a handful of uses in the code in question.
There is one other consideration, which is that tools are not as reliable yet at showing where your implicit conversions come from as where your methods come from. Thus, if I'm writing code that is difficult, and I expect that anyone who is using or maintaining it is going to have to study it hard to understand what is required and how it works, I--and this is almost backwards from a typical Java philosophy--am more likely to use PML in this fashion to render the steps more transparent to a trained user. The comments will warn that the code needs to be understood deeply; once you understand deeply, these changes help rather than hurt. If, on the other hand, the code's doing something relatively straightforward, I'm more likely to leave defs in place since IDEs will help me or others quickly get up to speed if we need to make a change.
Avoiding explicit conversions
I try to avoid explicit conversions. You certainly can write
implicit def string_to_int(s: String) = s.toInt
but it's awfully dangerous, even if you seem to be peppering all your strings with .toInt.
The main exception I make is for wrapper classes. Suppose, for example, you want to have a method take classes with a pre-computed hash code. I would
class Hashed[A](private[Hashed] val a: A) {
override def equals(o: Any) = a == o
override def toString = a.toString
override val hashCode = a.##
}
object Hashed {
implicit def anything_to_hashed[A](a: A) = new Hashed(a)
implicit def hashed_to_anything[A](h: Hashed[A]) = h.a
}
and get back whatever class I started with either automatically or, at worst, by adding a type annotation (e.g. x: String). The reason is that this makes wrapper classes minimally intrusive. You don't really want to know about the wrapper; you just need the functionality sometimes. You can't completely avoid noticing the wrapper (e.g. you can only fix equals in one direction, and sometimes you need to get back to the original type). But this often lets you write code with minimal fuss, which is sometimes just the thing to do.
Implicit parameters
Implicit parameters are alarmingly promiscuous. I use default values whenever I possibly can instead. But sometimes you can't, especially with generic code.
If possible, I try to make the implicit parameter be something that no other method would ever use. For example, the Scala collections library has a CanBuildFrom class that is almost perfectly useless as anything other than an implicit parameter to collections methods. So there is very little danger of unintended crosstalk.
If this is not possible--for example, if a parameter needs to be passed to several different methods, but doing so really distracts from what the code is doing (e.g. trying to do logging in the middle of arithmetic), then rather than make a common class (e.g. String) be the implicit val, I wrap it in a marker class (usually with an implicit conversion).
I don't believe I have come across anything, so let's create it here! Some rules of thumb:
Implicit Conversions
When implicitly converting from A to B where it is not the case that every A can be seen as a B, do it via pimping a toX conversion, or something similar. For example:
val d = "20110513".toDate //YES
val d : Date = "20110513" //NO!
Don't go mad! Use for very common core library functionality, rather than in every class to pimp something for the sake of it!
val (duration, unit) = 5.seconds //YES
val b = someRef.isContainedIn(aColl) //NO!
aColl exists_? aPred //NO! - just use "exists"
Implicit Parameters
Use these to either:
provide typeclass instances (like scalaz)
inject something obvious (like providing an ExecutorService to some worker invocation)
as a version of dependency injection (e.g. propagate the setting of service-type fields on instances)
Don't use for laziness' sake!
This one is so little-known that it has yet to be given a name (to the best of my knowledge), but it's already firmly established as one of my personal favourites.
So I'm going to go out on a limb here, and name it the "pimp my type class" pattern. Perhaps the community will come up with something better.
This is a 3-part pattern, built entirely out of implicits. It's also already used in the standard library (since 2.9). Explained here via the heavily cut-down Numeric type class, which should hopefully be familiar.
Part 1 - Create a type class
trait Numeric[T] {
def plus(x: T, y: T): T
def minus(x: T, y: T): T
def times(x: T, y: T): T
//...
}
implicit object ShortIsNumeric extends Numeric[Short] {
def plus(x: Short, y: Short): Short = (x + y).toShort
def minus(x: Short, y: Short): Short = (x - y).toShort
def times(x: Short, y: Short): Short = (x * y).toShort
//...
}
//...
Part 2 - Add a nested class providing infix operations
trait Numeric[T] {
// ...
class Ops(lhs: T) {
def +(rhs: T) = plus(lhs, rhs)
def -(rhs: T) = minus(lhs, rhs)
def *(rhs: T) = times(lhs, rhs)
// ...
}
}
Part 3 - Pimp members of the type class with the operations
implicit def infixNumericOps[T](x: T)(implicit num: Numeric[T]): Numeric[T]#Ops =
new num.Ops(x)
Then use it
def addAnyTwoNumbers[T: Numeric](x: T, y: T) = x + y
Full code:
object PimpTypeClass {
trait Numeric[T] {
def plus(x: T, y: T): T
def minus(x: T, y: T): T
def times(x: T, y: T): T
class Ops(lhs: T) {
def +(rhs: T) = plus(lhs, rhs)
def -(rhs: T) = minus(lhs, rhs)
def *(rhs: T) = times(lhs, rhs)
}
}
object Numeric {
implicit object ShortIsNumeric extends Numeric[Short] {
def plus(x: Short, y: Short): Short = (x + y).toShort
def minus(x: Short, y: Short): Short = (x - y).toShort
def times(x: Short, y: Short): Short = (x * y).toShort
}
implicit def infixNumericOps[T](x: T)(implicit num: Numeric[T]): Numeric[T]#Ops =
new num.Ops(x)
def addNumbers[T: Numeric](x: T, y: T) = x + y
}
}
object PimpTest {
import PimpTypeClass.Numeric._
def main(args: Array[String]) {
val x: Short = 1
val y: Short = 2
println(addNumbers(x, y))
}
}