I'm not sure what this pattern is called, but could this be written in scala and if so how would I go about doing this?
val userId = 1
def getUser(userId: Int): User = {
CacheLookup.getOrElse(userId) {
userDao.get(userId)
}
}
I guess this would be an anonymous function as a parameter?
There's something similar to that on maps -- check mutable map's withDefault. The difference is that it doesn't update the map, which seems to be what you want (and, in fact, what many people using withDefault wants, by the questions we get here).
An alternative is memoization. You'd have to find that outside the standard library, but it works a bit like that except you don't do the cache thing explicitly. Basically, you write a function userId => userDao.get(userId), and then you get a memoized version of it. When you call the memoized version, it will check whether there's a cached version for the parameter and serve that if so.
Note that there are important issues with the cache. Do you want/can have it increase indefinitely, or should it be limited? Will the keys expire after a time? This sort of control is important, and whatever solution you pick must support it.
As for how to implement it, it could go like this:
def memoize[A, B](f: A => B): A => B = {
var map = Map.empty[A, B]
(key: A) => {
if (!map.contains(key)) map += key -> f(key)
map(key)
}
}
val getUser = memoize((userId: Int) => userDao.get(userId))
This memoization function takes a Function1 (that is, a function with one parameter) and takes a Function1 that does caching (in a very basic sense, without any of the controls I mentioned). For functions taking more parameters you'd have to create different versions of this, or make them tupled.
Then we get to the use, where I pass the function that takes an userId (an Int) and returns a User, and we get the same function back, but now doing caching.
Here's an example of tupling, just out of curiosity:
scala> val mult = memoize(((x: Int, y: Int) => x * y).tupled)
mult: ((Int, Int)) => Int = <function1>
scala> mult(2, 3)
res18: Int = 6
scala> mult(2 -> 3)
res19: Int = 6
The first call, mult(2, 3) is actually a Scala oddity. When calling functions that take a tuple, if you are passing multiple parameters then Scala will auto-tuple then.
It's not entirely clear what you're asking. If you're wondering how to implement the getOrElse method so that the database call would only be conditionally evaluated, the answer is to just use an ordinary higher-order function:
def getOrElse(userId: Int)(getter: Int => User) =
if (cache contains userId)
cache get userId
else
getter(userId)
Related
I'm currently doing a Scala course and recently I was introduced to different techniques of returning functions.
For example, given this function and method:
val simpleAddFunction = (x: Int, y: Int) => x + y
def simpleAddMethod(x: Int, y: Int) = x + y
I can return another function just doing this:
val add7_v1 = (x: Int) => simpleAddFunction(x, 7)
val add7_v2 = simpleAddFunction(_: Int, 7)
val add7_v3 = (x: Int) => simpleAddMethod(x, 7)
val add7_v4 = simpleAddMethod(_: Int, 7)
All the values add7_x accomplish the same thing, so, whats the purpose of Currying then?
Why I have to write def simpleCurryMethod(x: Int)(y: Int) = x + y if all of the above functions do a similar functionality?
That's it! I'm a newbie in functional programming and I don't know many use cases of Currying apart from saving time by reducing the use of parameters repeatedly. So, if someone could explain me the advantages of currying over the previous examples or in Currying in general I would be very grateful.
That's it, have a nice day!
In Scala 2 there are only four pragmatic reasons for currying METHODS (as far as I can recall, if someone has another valid use case then please let me know).
(and probably the principal reason to use it) to drive type inference.
For example, when you want to accept a function or another kind of generic value whose generic type should be inferred from some plain data. For example:
def applyTwice[A](a: A)(f: A => A): A = f(f(a))
applyTwice(10)(_ + 1) // Here the compiler is able to infer that f is Int => Int
In the above example, if I wouldn't have curried the function then I would need to have done something like: applyTwice(10, (x: Int) => x + 1) to call the function.
Which is redundant and looks worse (IMHO).
Note: In Scala 3 type inference is improved thus this reason is not longer valid there.
(and probably the main reason now in Scala 3) for the UX of callers.
For example, if you expect an argument to be a function or a block it is usually better as a single argument in its own (and last) parameter list so it looks nice in usage. For example:
def iterN(n: Int)(body: => Unit): Unit =
if (n > 0) {
body
iterN(n - 1)(body)
}
iterN(3) {
println("Hello")
// more code
println("World")
}
Again, if I wouldn't have curried the previous method the usage would have been like this:
iterN(3, {
println("Hello")
// more code
println("World")
})
Which doesn't look that nice :)
(in my experience weird but valid) when you know that majority of users will call it partially to return a function.
Because val baz = foo(bar) _ looks better than val baz = foo(bar, _) and with the first one, you sometimes don't the the underscore like: data.map(foo(bar))
Note: Disclaimer, I personally think that if this is the case, is better to just return a function right away instead of currying.
Edit
Thanks to #jwvh for pointing out this fourth use case.
(useful when using path-dependant types) when you need to refer to previous parameters. For example:
trait Foo {
type I
def bar(i: I): Baz
}
def run(foo: Foo)(i: foo.I): Baz =
foo.bar(i)
Looking at Programming in Scala (control abstraction) I saw these two examples that have the same effect:
1. Higher-Order Function
def withPrintWriter(file: File, op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
2. Currying function
def withPrintWriter(file: File)(op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
What is the difference between them? Can we always achieve the same result in both ways?
The concepts of higher-order functions and curried functions are generally used in an orthogonal way. A higher-order function is simply a function that takes a function as an argument or returns a function as a result, and it may or may not be curried. In general usage, someone referring to a higher-order function is usually talking about a function that takes another function as an argument.
A curried function, on the other hand, is one that returns a function as its result. A fully curried function is a one-argument function that either returns an ordinary result or returns a fully curried function. Note that a curried function is necessarily a higher-order function, since it returns a function as its result.
Thus, your second example is an example of a curried function that returns a higher-order function. Here's another example of curried function that does not take a function as an argument, expressed in various (nearly equivalent) ways:
def plus(a: Int)(b:Int) = a + b
def plus(a: Int) = (b: Int) => a + b
val plus = (a: Int) => (b: Int) => a + b
Higher order functions are functions that either take functions as parameter or return functions or both.
def f(g: Int => Int) = g(_: Int) + 23
scala> f(_ + 45)
res1: Int => Int = <function1>
scala> res1(4)
res2: Int = 72
This is a higher order function, it takes a function as parameter and returns another function. As you can see, higher order functions are a pre-requisite for currying. The curry function looks like this:
def curry[A,B,C](f: (A,B) => C) = (a: A) => (b: B) => f(a,b)
scala> curry((a: Int, b: Int) => a+b)
res3: Int => (Int => Int) = <function1>
scala> res3(3)
res4: Int => Int = <function1>
scala> res4(3)
res5: Int = 6
So to answer your question: They are two different concepts, where the one (higher order functions) is the pre-requisit for the other (currying).
Semantically, there is one difference I can think of between a curried and a not curried function. With the non-curried version, when you call withPrintWriter, that's a single method call. With the curried version, it's actually going to be two method calls. Think of it like this:
withPrintWriter.apply(file).apply(op)
Other than that, I think a lot of people use currying in this kind of situation for style. Using currying here makes this look more like a language feature then just a custom function call because you can use it like this:
withPrintWriter(file){ op =>
...
}
Using it in that way is trying to emulate some sore of control structure from the language itself, but again, this is only really a style thing and it does come with the overhead of an additional method call.
You can use the non-curried version in almost the same way, but it's not as clean looking:
withPrintWriter(file, { op =>
...
})
EDIT
#drexin makes a good point in his answer that it's worth mentioning here for me. When you think of the signature of the curried version of the method, it's really:
Function1[File, Function1[PrintWriter, Unit]]
They are mostly the same, but there is a difference with regard to type inference. Scala is not able to infer types between arguments of a single method invocation, but it is able to infer types for multiple argument lists.
Consider:
def foo1[T](x : T, y : T => T) = y(x)
def foo2[T](x : T)(y : T => T) = y(x)
foo1(1, t => t + 1) //does not compile with 'missing parameter type'
foo2(1)(t => t + 1) //compiles
You can see some additional information in this answer : Multiple parameter closure argument type not inferred
Strictly speaking, the example you gave is not really curried, it just has multiple argument lists. It just happens that multiple argument list Scala functions look a lot like curried functions in many situations. However, when you call a multiple argument list function but don't fill in one or more argument lists, it's really an example of partial application, not currying. Calling a multiple argument list with all its arguments is just one function call, not one per argument list.
There are two use cases where multiple argument list functions are helpful. The first is the case of implicit parameters, since all implicit parameters have to be in their own argument list separate from any explicit parameters. The second use case is functions that accept other functions as parameters, since if a parameter that is a function is in its own argument list, you can leave off the parentheses and just use braces, making the function call look like some sort of control structure.
Other than that, the difference is purely cosmetic.
How to pass a tuple argument the best way ?
Example:
def foo(...): (Int, Int) = ...
def bar(a: Int, b: Int) = ...
Now I would like to pass the output of foo to bar. This can be achieved with:
val fooResult = foo(...)
bar(fooResult._1, fooResult._2)
This approach looks a bit ugly, especially when we deal with a n-tuple with n > 2. Also we have to store the result of foo in an extra value, because otherwise foo has to be executed more than once using bar(foo._1, foo._2).
Is there a better way to pass through the tuple as argument ?
There is a special tupled method available for every function:
val bar2 = (bar _).tupled // or Function.tupled(bar _)
bar2 takes a tuple of (Int, Int) (same as bar arguments). Now you can say:
bar2(foo())
If your methods were actually functions (notice the val keyword) the syntax is much more pleasant:
val bar = (a: Int, b: Int) => //...
bar.tupled(foo())
See also
How to apply a function to a tuple?
It is worth also knowing about
foo(...) match { case (a,b) => bar(a,b) }
as an alternative that doesn't require you to explicitly create a temporary fooResult. It's a good compromise when speed and lack of clutter are both important. You can create a function with bar _ and then convert it to take a single tuple argument with .tupled, but this creates a two new function objects each time you call the pair; you could store the result, but that could clutter your code unnecessarily.
For everyday use (i.e. this is not the performance-limiting part of your code), you can just
(bar _).tupled(foo(...))
in line. Sure, you create two extra function objects, but you most likely just created the tuple also, so you don't care that much, right?
Using tupled, as #Tomasz mentions, is a good approach.
You could also extract the tuple returned from foo during assignment:
val (x, y) = foo(5)
bar(x, y)
This has the benefit of cleaner code (no _1 and _2), and lets you assign descriptive names for x and y, making your code easier to read.
I have two functions with different type signatures, and I want to store them both in a Map:
val add = ((a: Int, b: Int) => a + b)
val odd = ((a: Int) => a % 2 == 0)
var funcs = Map[String, Any]("add" -> add, "odd" -> odd)
Then I want to access these functions at a later date, without having to know about their types. How would I do this? I can write:
funcs("add").asInstanceOf[(Int, Int) => Int](1, 2)
But that requires me to either
know ahead of time what the type of the function is
do some sort of pattern match that accounts for every possible type.
Is there some way I can find out the type of the object stored as Any and convert it to that type?
Although this certainly is not a good idea, if you really have to do it, you can do it using reflection.
Using PaulP's Invocation utility:
scala> val add: (Int, Int) => Int = _ + _
add: (Int, Int) => Int = <function2>
scala> val isOdd: Int => Boolean = _ % 2 != 0
isOdd: Int => Boolean = <function1>
scala> import Invocation._
import Invocation._
scala> val funcs = Map("add" -> add, "isOdd" -> isOdd)
funcs: scala.collection.immutable.Map[java.lang.String,ScalaObject] = Map(add -> <function2>, isOdd -> <function1>)
scala> funcs("add") o 'apply(3, 4)
res18: Any = 7
scala> funcs("isOdd") o 'apply(11)
res19: Any = true
Is there some way I can find out the type of the object stored as Any and convert it to that type?
This doesn't actually make sense. Lets suppose I could do it, and it looks like this:
val func = funcs(func_name).toAppropriateType
Now what?
func now holds a value of some unknown type. I can call it... but I don't know its signature, so what arguments do I pass it? And the type/signature is going to be different on every invocation (depending on what was pulled out of the map), so the code to call it is going to have to be different for every invocation; I need some way of having different code executed for each possibility of func... but that would be a pattern match! And it would have to account for every possible type, just as match on Any.
In fact, the magical toAppropriateType method, even if it could exist, gains me nothing on top of just using an Any. It's still the case that the only things I can do with func are things you can do with all values of every possible type (i.e. very little).
In general, when you take something out of a collection you have to handle it with code that is valid for anything that the type allows to be put into the collection. The only alternative is to use features such as asInstanceOf, which throws away the guarantees of the type system and puts the responsibility for ensuring that you don't use the wrong type on you; meaning you have to have some other way of knowing what type to expect, outside of the type system.
If you want to have a collection of functions with one of a pre-determined set of signatures then the best way is to construct a type that only allows those signatures, and allows you to tell the difference between them (such as Rex Kerr's suggestion of using Either). Switching to using Any as soon as you find you need to combine things of different types in a collection usually causes more problems than it solves.
You could store them in an Either:
val funcs = Map[String, Either[Int=>Boolean, (Int,Int)=>Int]](
"add" -> Right(add),
"odd" -> Left(odd)
)
Now you can pull them apart again, though pattern matching is finicky here (Right(f) will work, but don't try to put conditions on what f is). I suggest using fold, right, left (and isRight and isLeft if you really must), like so:
def doSomething(s: String) =
funcs(s).fold(
f => { f(4) }, // Left is Int=>Boolean
g => { g(3,5)==8 } // Right is (Int,Int)=>Int
)
Presumably you'd want some way to load appropriate arguments also instead of the dummy values I put in.
If you have many variants of functions, you can define your own either-like hierarchy except with more different cases, or you can nest Eithers.
I have a loan pattern that applies a function n times where 'i' is the incrementing variable. "Occasionally", I want the function passed in to have access to 'i'....but I don't want to require all functions passed in to require defining a param to accept 'i'. Example below...
def withLoaner = (n:Int) => (op:(Int) => String) => {
val result = for(i <- 1 to n) yield op(i)
result.mkString("\n")
}
def bob = (x:Int) => "bob" // don't need access to i. is there a way use () => "bob" instead?
def nums = (x:Int) => x.toString // needs access to i, define i as an input param
println(withLoaner(3)(bob))
println(withLoaner(3)(nums))
def withLoaner(n: Int) = new {
def apply(op: Int => String) : String = (1 to n).map(op).mkString("\n")
def apply(op: () => String) : String = apply{i: Int => op()}
}
(not sure how it is related to the loan pattern)
Edit Little explanation as requested in comment.
Not sure what you know and don't know of scala and what you don't undestand in that code. so sorry if what I just belabor the obvious.
First, a scala program consist of traits/classes (also singleton object) and methods. Everything that is done is done by methods (leaving constructor aside). Functions (as opposed to methods) are instances of (subtypes of) the various FunctionN traits (N the number of arguments). Each of them has as apply method that is the actual implemention.
If you write
val inc = {i: Int => i + 1}
it is desugared to
val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}
(defines an anonymous class extending Function1, with given apply method and creating an instance)
So writing a function has rather more weight than a simple method. Also you cannot have overloading (several methods with the same name, differing by the signature, just what I did above), nor use named arguments, or default value for arguments.
On the other hand, functions are first classes values (they can be passed as arguments, returned as result) while methods are not. They are automatically converted to functions when needed, however there may be some edges cases when doing that. If a method is intended solely to be used as a function value, rather than called as a method, it might be better to write a function.
A function f, with its apply method, is called with f(x) rather than f.apply(x) (which works too), because scala desugars function call notation on a value (value followed by parentheses and 0 or more args) to a call to method apply. f(x) is syntactic sugar for f.apply(x). This works whatever the type of f, it does not need to be one of the FunctionN.
What is done in withLoaner is returning an object (of an anonymous type, but one could have defined a class separately and returned an instance of it). The object has two apply methods, one accepting an Int => String, the other one an () => String. When you do withLoaner(n)(f) it means withLoaner(n).apply(f). The appropriate apply method is selected, if f has the proper type for one of them, otherwise, compile error.
Just in case you wonder withLoaner(n) does not mean withLoaner.apply(n) (or it would never stop, that could just as well mean withLoaner.apply.apply(n)), as withLoaner is a method, not a value.