What does A => A = a => a mean in scala - scala

I found following syntax in scala which i dont understand
object Category {
def id[A]: A => A = a => a
}
Especially this part A = a => a
Who can it be translated in a more readable syntax

This line:
def id[A]: A => A = a => a
defines a method named id which has a type argument A.
The return type of the method is A => A, which is: a function that takes an A and returns an A.
The part after the =: a => a is the body of the id method. It's a function literal for a function that takes a value a and returns the same thing a.
The part that you are specifically asking about: A = a => a is not a part by itself. The A => A is the return type of the method id, and the a => a is the body of the method. Just like with any other method, the = between these two parts separates the method declaration from the method body.
You could write the same thing like this:
def id[A]: Function1[A, A] = a => a

It's a method that returns a function which takes an A and returns another A and the function it is returning is an identity (you get a variable a of type A and just return it):
scala> object Category {
| def id[A]: A => A = a => a
| }
defined module Category
scala> Category.id[Int]
res0: Int => Int = <function1>
scala> res0(0)
res2: Int = 0
Not sure what are you trying to achieve here to be honest.

Related

Scala: am I writing a curried function?

I have to transform the following function into a curried function:
def findAllUsed(t: List[Task]): List[String] = {
t.flatMap(x => x.resources.map(x => x.FIELD_TO_SEARCH)).distinct
}
So I did this:
def findAllUsed(t: List[Task], f: Resource => String): List[String] = {
t.flatMap(x => x.resources.map(f)).distinct
}
findAllUsed(taskSchedules, ((x: Resource) => { x.id }))
findAllUsed(taskSchedules, ((x: Resource) => { x.kind }))
The problem is that it seems to me that I am confusing currying with higher order functions.
Can anyone if I am doing it right and if not, how could I manage to do it right?
I'm assuming the exercise meant something like this:
// separate into two argument lists
def findAllUsed(t: List[Task])(f: Resource => String): List[String] = {
t.flatMap(x => x.resources.map(f)).distinct
}
// apply the first argument list once,
// getting a curried function as a result
val curried = findAllUsed(taskSchedules)
// now you can use it twice with different inputs for the second argument list:
curried(x => x.id)
curried(x => x.kind)
The benefit here (if there is any), is the removal of the duplication passing taskSchedules to your function: since it has "it's own" argument list, you can pass it once, assign the result into a value (curried), and then reuse it over and over;
p.s. the type of curried is (Resource => String) => List[String] - it's a function from a Resource => String (which is another function...) to a list of strings.

Accepting functions of Any type in scala

Consider following code:
val x: Any = 3 // Int assignable to Any
def k(x:Any){ 3 }
println(k(2)) // Int assignable to Any
def g(h: Any => Any): Unit = h()
def f = (x:Int) => 3
println(g(f)) // type mismatch error: Int => Int not assignable to Any => Any
Questions:
Why is Int assignable to Any, but Int => Int is not?
How to make this work? How to declare a function type that accepts and returns any type of value?
Edit:
Thanks to GPI, it could be made to work like this:
def g = (x:Int) => x*x
def holder[In, Out](f: In => Out, v:In) = { f(v) }
println(holder(g, 3))
Well your assertions are not totally exact.
E.g.a function of type Int => Int is indeed an Any:
scala> val iToi = (input: Int) => input
iToi: Int => Int = <function1>
scala> iToi(3)
res0: Int = 3
scala> val test: Any = iToi
test: Any = <function1>
The issue you have is indeed that a Int => Int is not a Any => Any but this one is easy to understand :
A Any => Any function accepts anything as an argument, for example, a String.
A Int => Int does not accept a String as an argument
Therefore it should not, and is not, possible to take a Int => Int and "cast" it to a Any => Any.
The otherway around
A Any => Any returns anyting as a result, it can return a String or an Int.
A Int => Int returns an Int.
If we restrict ourselves to a view of the result side of the function, they are compatible.
And indeed, we can say :
scala> val test2: Int => Any = iToi
test2: Int => Any = <function1>
This works.
One could write a generic function accepting any kind of function this way (but there are many more I'd bet are better, I'm not that good in Scala yet :-) ) :
scala> def holder[In, Out](f: In => Out) = { f.toString }
holder: [In, Out](f: In => Out)String
scala> holder(iToi)
res0: String = <function1>
When you deal with T => R function, in reality you have object of class
Function1[#scala.specialized -T1, #scala.specialized +R]
with two class parameters.
First parameter (T in our case) is in contravariant position (minus in front of T1), so you can not provide sub type when it wants super type.
So either change signature of f to def f = (x:Any) => 3
or alternatively parameter of g to Int => Any

Unsure how this returns an Int of functions

I'm reading this scala book and a bit unsure on what this syntax translates to:
def bf: Int => Int => Int = i => v => i + v
bf is the name of the function.
after then colon is the function return type which is:
Int => Int => Int
I presume that the equal sign is the start of the function body, but not sure because then it has i => v => i + v.
Can someone clarify where each return type is and how to you break it down in your head so I can do the same :)
Short answer:
return type of the code can be read as Int => (Int => Int).
It is a function that takes single parameter of Int and returns a function that takes another Int parameter and returns Int.
If you are still getting confused, this is the longer way to write the same.
val bf: Int => (Int => Int) = (a:Int) => ((b: Int) => a + b)
|_________________| |____________________________|
type outer function
|________________|
inner func returned by the outer func
Long answer:
It is normally called curried function or function currying.
I assume You already noticed this though, This method originally trying to get sum of 2 Int values which is written as below.
val foo = (a: Int,b: Int) => a + b
any functions which takes multiple parameters can be transformed to nested single parameter functions a.k.a "curried function".
You may write it by your self just like your question code but You can call .curried to the method/function to get it as well.
val bf = foo.curried //bf is exactly the same thing as you wrote
This is usually used when you can't define both of the parameters at the same time so when you gets first value, make a function that (b: Int) => YOUR_FIRST_VALUE_ALREADY_DEFINED + b. and call it when you get second value.
How the curried function is used...
bf(4)(5) //9
val bar = bf(6) // (Int) => Int
bar(7) // 13
functional types are associate to the right.
for e.g.
Int => Int => Int is equivalent to Int => (Int => Int)
more details you can register and go through below lecture.
https://www.coursera.org/learn/progfun1/lecture/fOuQ9/lecture-2-2-currying

Set default value for function parameter in scala

I am trying to set a default value to an anonymous function in scala and so for not able to find any solution. Hope some one would help me out in SO.
I have the following structure,
case class A(id:Int = 0)
case class B(a:A)
object B {
def func1(f:Int = 0)={
........
}
def func2(f:A => B = (how to give default value ?))={
case Nothing => {
//do something....
}
case _ => {
//do some other thing......
}
}
}
Basically, I want to make passing the parameter as optional. How can I achieve this?
Like any other default parameter:
scala> def test(f: Int => Int = _ + 1) = f
test: (f: Int => Int)Int => Int
scala> test()(1)
res3: Int = 2
or with String:
scala> def test(f: String => String = identity) = f
test: (f: String => String)String => String
scala> test()
res1: String => String = <function1>
scala> test()("Hello")
res2: String = Hello
Edit:
In case if you want to use a function provided by default, you have to use () explicitly, either Scala won't paste a default argument.
If you don't wanna use a default function and provide an explicit one, just provide it yourself:
scala> test(_.toUpperCase)("Hello")
res2: String = HELLO
Use an implicit parameter. Place an implicit value for the parameter in the object. This will be used unless you provide an explicit parameter or you have provided another implicit value in the calling scope.
case class A(id:Int = 0)
case class B(a:A)
object B {
implicit val defFunc: A => B = {a: A => new B(a) }
def func1(f:Int = 0)={
}
def func2(implicit func: A => B) = { ... }
}
The differences between this method and Alexlv's method are
This works with standalone functions as well as methods.
The scope rules allow for providing appropriate overrides in appropriate scopes. Alex's method would require subclassing or eta-expansion (with partial application) to change the default.
I offer this solution since you are already using an object. Otherwise, Alexvlv's example is simpler.
The other answers show how to provide some existing default value, but if you want the default to do nothing (as suggested by case Nothing) then you can use Option/None.
def func2(f:Option[A => B] = None)={
case Some(f) =>
//do something....
case None =>
//do some other thing......
}
func2()
func2( Some(_ + 1) )

In Scala, can generic type parameters be used with *function* definitions?

Is there a syntax to allow generic type parameters on function literals? I know I could wrap it in a method such as:
def createLongStringFunction[T](): (T) => Boolean = {
(obj: T) => obj.toString.length > 7
}
but then I end up needing to invoke the method for every type T and getting a new function. I looked through the language reference, and while I see that the function literal syntax is translated by the compiler to an instance of a Functionn object that itself has generic input types, it looks like the compiler magic realizes those parameters at the time of creation. I haven't found any syntax that allows me to, in effect, "leave one or more of the type parameters of Functionn unbound". What I would prefer is something along the lines of:
// doesn't compile
val longStringFunction: [T](T) => Boolean = (obj: T) => obj.toString.length > 7
Does any such thing exist? Or for that matter, what is the explicit type of an eta-expansion function when the method being expanded has generic parameters?
This is a purely contrived and useless example. Of course I could just make the function use Any here.
No, type parameters only apply to methods and not function objects. For example,
def f[T](x: T) = x //> f: [T](x: T)T
val g = f _ //> g: Nothing => Nothing = <function1>
// g(2) // error
val h: Int=>Int = f _ //> h : Int => Int = <function2>
h(2) //> res0: Int = 2
The method f cannot be converted to a polymorphic function object g. As you can see, the inferred type of g is actually Function1[Nothing, Nothing], which is useless. However, with a type hint we can construct h: Function1[Int,Int] that works as expected for Int argument.
As you say, in your example all you're requiring is the toString method and so Any would be the usual solution. However, there is call for being able to use higher-rank types in situations such as applying a type constructor such as List to every element in a tuple.
As the other answers have mentioned, there's no direct support for this, but there's a relatively nice way to encode it:
trait ~>[A[_],B[_]] {
def apply[X](a : A[X]) : B[X]
}
type Id[A] = A //necessary hack
object newList extends (Id ~> List) {
def apply[X](a : Id[X]) = List(a)
}
def tupleize[A,B, F[_]](f : Id ~> F, a : A, b : B) = (f(a), f(b))
tupleize(newList, 1, "Hello") // (List(1), List(Hello))
Since longStringFunction defined as followed is a value, which must have some given type.
val longStringFunction: (T) => Boolean = (obj: T) => obj.toString.length > 7
However, you can reuse a function object with a method:
scala> val funObj: Any => Boolean = _.toString.size > 7
funObj: Any => Boolean = <function1>
scala> def typedFunction[T]: T => Boolean = funObj
typedFunction: [T]=> T => Boolean
scala> val f1 = typedFunction[String]
f1: String => Boolean = <function1>
scala> val f2 = typedFunction[Int]
f2: Int => Boolean = <function1>
scala> f1 eq f2
res0: Boolean = true
This works because trait Function1[-T1, +R] is contravariant of type T1.
In scala, Function values are parametrically monomorphic(while methods are polymorphic)
Shapeless library introduces polymorphic function values which may be mapped over HLists and many more other features.
Please consider the following refs:
http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/
http://www.chuusai.com/2012/05/10/shapeless-polymorphic-function-values-2/