Understanding curried function passed in to fold - scala

I am having problems understanding this code from the Book FP in Scala. Here is the code:
trait Monoid[A] {
def op(a1: A, a2: A): A
def zero: A
}
def endoMonoid[A]: Monoid[A => A] = new Monoid[A => A] {
def op(f: A => A, g: A => A) = f compose g
val zero = (a: A) => a
}
def foldMap[A, B](as: List[A], m: Monoid[B])(f: A => B): B =
as.foldLeft(m.zero)((b, a) => m.op(b, f(a)))
// The function type `(A, B) => B`, when curried, is `A => (B => B)`.
// And of course, `B => B` is a monoid for any `B` (via function composition).
def foldRight[A, B](as: List[A])(z: B)(f: (A, B) => B): B =
foldMap(as, endoMonoid[B])(f.curried)(z)
foldMap is expecting a function f: A => B.
In foldRight, when f is curried you have A => (B => B), so I suppose f.curried is working because it is the same as (A => B => B), so foldRight is passing in to foldMap what it expect (a function with type A => B), then, what happends next is that foldMap is called and its returning a function B => B, and that's when z comes into play in (f.curried)(z) you call the function B => B with the argument z to get the final B.
Am I right? it is a litle complicated to reason about this code for me.
NOTE: Here is a scalafiddle if you want to play with it.

Well, you seem to be mostly comprehensive to me. Nevertheless, I would clarify some points:
I'd rather say "so I suppose f.curried is working because A => (B => B) is the same as (A => B => B)" (it is ambiguous here and you're talking about f.curried result type basically, not with z)
I'd rather put a point instead of a comma here: "foldMap is expecting a function f: A => B . In foldRight, ... " and pretty much every where else. Shorter phrases, clearer explanation.
what could be an error, (and what is confusing to you?) is that (f.curried)(z) doesn't work on its own and is not called after foldMap(as, endoMonoid[B]). It's first foldMap(as, endoMonoid[B])(f.curried) which is called and then (z). The first returns B => B and called with the second returns B.

Related

scala generic function reference

I have several generic functions with the same signature:
def f1[A, B](v: A, f: (A, B) => B): B = ...
def f2[A, B](v: A, f: (A, B) => B): B = ...
And I need to define a function g that can accept any of these functions (f1 f2):
def g(f: ????) = ...
g internally uses multiple argument types, so I can not parameterize it like that:
def g[A, B](f: (A, (A, B) => B) => B) = ...
There isn't really a much better way to do it in Scala 2. Although your solution is a bit strange because FunctionHolder's apply method will return a function object and doesn't accept any arguments itself – that's a bit more complicated than it needs to be. So you can do this instead:
trait FunctionHolder {
def apply[A, B](v: A, f: (A, B) => B): B
}
def g(f: FunctionHolder) = …
But this isn't really all that much better.
In Scala 3, there are polymorphic function types to do this in a cleaner way:
def g(f: [A, B] => (A, (A, B) => B) => B) = …
That said, I'm not convinced that that type signature is really what you want. Remember, when you define a function with type parameters, it needs to work for all possible type parameters that the user might supply. This can't be done for this signature…
def f1[A, B](v: A, f: (A, B) => B): B
… because when I have a function like that, I can easily write an expression of type Nothing:
f1[Unit, Nothing]((), (a: Unit, b: Nothing) => b)
and it's not possible to write an expression of type Nothing unless you cheat (e. g. throw an exception or enter an infinite loop or something like that). So the type signature tells me you're cheating 😉
If you want to know more about this kind of reasoning, search for “Theorems for free!”
After wandering a bit, come up with following:
g(new FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B = f1
})
def g(f: FunctionHolder) = f()(..., (a, b) => ...)
abstract class FunctionHolder {
def apply[A, B](): (A, (A, B) => B) => B
}
But that just does not look right.
Hope there are more concise ways to do that

Why this example of fpinscala works?(no argument name)

all:
I'm a newbie to scala. I'm not quite understanding an example of curry in the book "functional programming in scala".
Why a function without variables like a, b can be compiled and run smoothly?
def curry[A,B,C](f: (A, B) => C): A => (B => C) =
a => b => f(a, b)
In Scala parameterName => body is an anonymous function that takes a parameter named parameterName and whose body is body.
So a => b => f(a,b) is a function with the parameter a and the body b => f(a,b), which is itself a function with the parameter b and the body f(a,b). In that body a and b are defined because they're parameters.
If that makes it less confusing for you, we can rewrite this using named functions instead:
def curry[A,B,C](f: (A, B) => C): A => (B => C) = {
def f1(a: A) = {
def f2(b: B) = f(a,b)
f2
}
f1
}
It is because
a => b => f(a, b)
is anonymous function (lambda). a and b are variables without any value at the time. They are used only to construct the function (note that curry function return type is another function)

What is happening under the covers in this scala code?

I have the following scala code (from the FP In Scala book):
import scala.{Option => _, Either => _, Left => _, Right => _, _} // hide std library `Option` and `Either`, since we are writing our own in this chapter
case class Left[+E](get: E) extends Either[E,Nothing]
case class Right[+A](get: A) extends Either[Nothing,A]
sealed trait Either[+E,+A] {
def map[B](f: A => B): Either[E, B] = this match {
case Right(r) => Right(f(r))
case Left(e) => Left(e)
}
def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] = this match {
case Right(r) => f(r)
case Left(e) => Left(e)
}
def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = {
this flatMap(aa => b map (bb => f(aa, bb)))
}
}
I would like to know what is going on when I call map2 like this:
val b = fpinscala.errorhandling.Right(2)
val a = fpinscala.errorhandling.Right("right")
val f = (a: String, b:Int) => a + b
a.map2(b)(f)
How does scala know to use substitute this (i.e. a) into the aa in this line of code: this flatMap(aa => b map (bb => f(aa, bb))) in the map2 function?
#jcm, see if this makes any sense.
a.map2(b)(f)
We're calling the map2 method of the a object. Inside the method code a is now referenced as this.
this flatMap(aa => b map (bb => f(aa, bb)))
Now we're calling the flatMap method of the this object (which is still a).
What does flatMap take as an argument? It takes a function, a function that takes an argument (of some type that we'll refer to as "A") and returns an Either. So that means that everything between the parentheses is that function. That function has no name (i.e. no def statement) so it's often called an anonymous function.
That function takes an argument. This code aa => identifies the argument so that it can be referred to later in the function. "aa" is just an arbitrary name. We could have used "thisthat" or "xyz".
Where does the value that aa contains come from? It comes out of this. Consider the following code.
List(4,7,9).map(x => 42 - x)
In this case map invokes the anonymous function three times, once for every value from the List. x takes on a new value (first 4, then 7, then 9) every time the function is invoked.
If that all makes any sense then apply the same logic to b map (bb => .....) and you're almost home!
How does scala know to use substitute this (i.e. a) into the aa
aa is not replaced with this. aa is replaced with the string "right".
The replacement is done by flatMap here:
case Right(r) => f(r)
flatMap checks if this instance of Either is a Right or a Left. If it is a Right, then it feeds its content (the string "right") into the function f (aa => b map (bb => f(aa, bb))).
How does scala know to use substitute this (i.e. a) into the aa in
this line of code: this flatMap(aa => b map (bb => f(aa, bb))) in the
map2 function?
It is not. What is going on here is this:
A closure is being built, which takes an Either[EE,B], calls it aa and computes b map (bb => f(aa, bb). b and f are taken from the parent scope.
this.flatMap is being called, given that function as a parameter.
Read more on Scala closures :-)

Getting Last Type of Curried Function

Given a val that consists of the following (what I believe is a) type constructor with a curried function argument, F[A => B => C]...
val x: F[A => B => C] = foo() // foo does not matter
Is it possible for me to get F[C] from x?
val y: F[C] = x...
EDIT
For context, I'm trying to implement the map3 function from Functional Programming in Scala.
The only way to get F[C] from F[A => B => C] is if you can apply an A and a B to it. That is, you'll need to evaluate the contained function. Use the apply twice, once to get an B => C and then once again to get C.
def eval(myApp: F[A => B => C])(value: F[A]): F[B => C]
def evalAgain(myApp: F[B => C])(value: F[B]): F[C]
but if you just want to be able to get F[C] directly from the function itself without evaluation, you're SOL.
Edit:
I believe it would look like this.
def eval(myApp: F[A => B => C])(value: F[A], next: F[B])(implicit ap: Applicative[F[_]]) = ap(ap(myApp, value), next)

Why is currying and uncurrying not implicit in scala

If I have a function:
f : A => B => C
I can define an implicit conversion such that this can be used where a function (A, B) => C is expected. This goes in the other direction also.
Why are these conversions not implicit (or available implicitly)? I am assuming that bad things could happen for some value of bad things. What value is this?
I don't think anything bad will happen. The conversion is completely unambiguous. Worst case, Scala will not be able to figure out that the implicit conversion applies.
implicit def curryImplicitly[A,B,C](f: (A, B) => C) =
(a: A) => (b: B) => f(a, b)
implicit def uncurryImplicitly[A,B,C](f: A => B => C) =
(a: A, b: B) => f(a)(b)
Then again, these would also be helpful.
implicit def flipImplicitly[A,B,C](f: (A, B) => C) =
(b: B, a: A) => f(a, b)
implicit def flipImplicitlyCurried[A,B,C](f: A => B => C) =
(b: B) => (a: A) => f(a)(b)
But those aren't transitive, so you need these:
implicit def flipAndCurry[A,B,C](f: (A, B) => C) =
(b: B) => (a: A) => f(a, b)
implicit def flipAndUncurry[A,B,C](f: A => B => C) =
(b: B, a: A) => f(a)(b)
But now the conversion is ambiguous. So it's not all roses.
Let's know how it works out in practise. You might need equivalents for Function3, Function4, etc.
You don't want them implicitly available by default (always-on) because then the type system has trouble helping you out when you have overloaded with arguments of a bunch of similar types:
A => B => C
D => C // D is allowed to be a tuple (A,B)...
(A,B) => C // If I have this, to whom should I convert?
Part of the advantage of strong typing is warning you when you've done something foolish. Trying too hard to make things work reduces the benefits. Here, if the conversions were done automatically, you might not call the method you meant to call.
Having them available implicitly upon request is fine, but it's not that hard to do it yourself if you need it. This is something that I would use quite rarely; I wouldn't put it in my top ten or probably even top hundred things that I'd like in the library (in part because I might prefer the automatic conversion to a tuple instead of the automatic currying/uncurrying).