I am confused about what this means.
I understand currying but I can't seem to read the code altogether.
def foldLeft [A,B](xs:List[A], e:B, f:(B,A)=>B): B
Let's dive into this method signature:
foldLeft[A,B](xs: List[A], e: B, f: (B, A) => B): B
foldLeft is a method with 3 parameters
A and B are type parameters
xs is 1st parameter of the method, of type List[A]
e is 2nd parameter, of type B
f is 3rd parameter, of type (B, A) => B
the type (B, A) => B represents a function taking two parameters of type B and A respectively, and returning a B
finally, B is the return type of the method
Just a couple of advices.
By the way, there is no currying in
def foldLeft[A,B](xs: List[A], e: B, f: (B, A) => B): B
Currying would be if you had f: B => A => B or def foldLeft[A, B](xs: List[A])(e: B)(f: (B, A) => B): B or def foldLeft[A, B]: List[A] => B => ((B, A) => B) => B etc. Now foldLeft is just a higher-order function (method), i.e. a function accepting another function (f).
You can read wiki article about foldRight/foldLeft:
https://en.wikipedia.org/wiki/Fold_(higher-order_function)
Especially look at the pictures how we deconstruct a list and starting from what end we perform our calculations:
You can think of foldRight/foldLeft as a just short way to define a recursion (instead of pattern matching a list and making recursive calls).
Let's consider an example. Let's have some recursion. For example let's have a wrapper class
case class Value[A](value: A)
And let's transform a list of Value[A] into a value wrapping a list of A i.e. List[Value[A]] into Value[List[A]]. For example we'd like to transform List(Value(1), Value(2), Value(3)) into Value(List(1, 2, 3)) (I actually needed such function recently). Surely, we could do this with .map but let's pretend that we don't know map (it shouldn't be surprising that we can do mapping because map can be expressed via foldRight/foldLeft).
We can do this recursively in two ways (at least). Either simple recursion
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] = values match {
case Nil => Value(Nil)
case v :: vs => Value(v.value :: valuesToValue(vs).value)
}
or tail recursion with a helper function and accumulator
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] = {
#tailrec
def loop(values: List[Value[A]], acc: Value[List[A]]): Value[List[A]] = values match {
case Nil => Value(acc.value.reverse)
case v :: vs => loop(vs, Value(v.value :: acc.value))
}
loop(values, Value(Nil))
}
Very simple. Just wrapping-unwrapping.
Both recursive implementations of valuesToValue can be (automatically) re-written with foldRight/foldLeft.
The former recursion can be re-written with foldRight. The latter recursion (tail one) can be re-written with foldLeft.
Let's re-write the 1st recursion with foldRight. The value from branch case Nil => ... becomes the 1st argument of foldRight. The value from branch case v :: vs => ... becomes the 2nd argument of foldRight if we replace the result of recursive call valuesToValue(vs) with a new variable res, so in the 2nd argument of foldRight we'll have a function of v: Value[A] and res: Value[List[A]]
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] =
values.foldRight( Value(Nil: List[A]) ){
(v, res) => Value(v.value :: res.value)
}
Let's re-write the 2nd recursion (tail one) with foldLeft.
First of all, let's recall that because of currying we can understand the helper loop as a single-parameter function into Value[List[A]] => Value[List[A]]
def loop(values: List[Value[A]]): Value[List[A]] => Value[List[A]] = values match {
case Nil => acc => Value(acc.value.reverse)
case v :: vs => acc => loop(vs)(Value(v.value :: acc.value))
}
Now the value from branch case Nil => ... becomes the 1st argument of foldLeft. The value from branch case v :: vs => ... becomes the 2nd argument of foldLeft if we replace the result of recursive call loop(vs)(_) with a new variable res (a function)
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] = {
def loop(values: List[Value[A]]): Value[List[A]] => Value[List[A]] =
values.foldRight[Value[List[A]] => Value[List[A]]](
acc => Value(acc.value.reverse)
)(
(v, res) => acc => res(Value(v.value :: acc.value))
)
loop(values)(Value(Nil))
}
So, roughly speaking, values from branches case Nil => ... and case v :: vs => ... become arguments of foldRight/foldLeft depending on whether we calculate with simple recursion or tail recursion with accumulator.
Related
I'm new to the Scala world and have some questions regarding following code.
sealed trait Input
case object Coin extends Input
case object Turn extends Input
case class Machine(locked: Boolean, candies: Int, coins: Int)
object Candy {
def update = (i: Input) => (s: Machine) =>
(i, s) match {
case (_, Machine(_, 0, _)) => s
case (Coin, Machine(false, _, _)) => s
case (Turn, Machine(true, _, _)) => s
case (Coin, Machine(true, candy, coin)) =>
Machine(false, candy, coin + 1)
case (Turn, Machine(false, candy, coin)) =>
Machine(true, candy - 1, coin)
}
def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
_ <- sequence(inputs map (modify[Machine] _ compose update))
s <- get
} yield (s.coins, s.candies)
}
case class State[S, +A](run: S => (A, S)) {
def map[B](f: A => B): State[S, B] =
flatMap(a => unit(f(a)))
def map2[B,C](sb: State[S, B])(f: (A, B) => C): State[S, C] =
flatMap(a => sb.map(b => f(a, b)))
def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => {
val (a, s1) = run(s)
f(a).run(s1)
})
}
object State {
def modify[S](f: S => S): State[S, Unit] = for {
s <- get // Gets the current state and assigns it to `s`.
_ <- set(f(s)) // Sets the new state to `f` applied to `s`.
} yield ()
def get[S]: State[S, S] = State(s => (s, s))
def set[S](s: S): State[S, Unit] = State(_ => ((), s))
def sequence[S,A](sas: List[State[S, A]]): State[S, List[A]] =
sas.foldRight(unit[S, List[A]](List()))((f, acc) => f.map2(acc)(_ :: _))
def unit[S, A](a: A): State[S, A] =
State(s => (a, s))
}
In simulateMachine method, what is the first and second _? Feels first one is an ignored output, are those two stands for the same value?
The get is from State, how does it get the state of Machine?
yield output a Tuple, how does it matching return type State[Machine, (Int, Int)]
How to call this simulateMachine method? Looks like I need do initiate Machine state somewhere.
I don't think this document can give me the right comprehension about what is happening under the hood. How can I understand it better?
Here's a slightly more verbose version of simulateMachine that should be a bit easier to understand.
def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
_ <- State.sequence( // this _ means "discard this 'unpacked' value"
inputs.map(
(State.modify[Machine] _).compose(update) // this _ is an eta-expansion
)
)
s <- State.get
} yield (s.coins, s.candies)
"Unpacked" value - for { value <- container } ... basically "unpacks" value from container. Semantics of unpacking is different between different containers - the most straightforward is List or Seq semantics, where value each item of the becomes value and for semantics in this case becomes just iteration. Other notable "containers" are:
Option - for semantics: value present or not + modifications of the value if present
Try - for semantics: successful computation or not + modifications of the successful
Future - for semantics: defining a chain of computations to perform when value becomes present
Practically, each monad (explaining what monad is is haaard :) Try this as a starting point) defines the way to "unpack" and "iterate". Your State is practically a monad (even though it doesn't declare this explicitly) (and btw, there's a canonical State monad you can find in 3rd party libs such as cats or scalaz)
Eta-expansion is explained in this SO answer, but in short it converts a function/method into a function object. Roughly equivalent to x => State.modify[Machine](x)
Or a completely desugared version:
def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = {
val simulationStep: Input => State[Machine, Unit] = (State.modify[Machine] _).compose(update) // this _ is an eta-expansion
State.sequence(inputs.map(input => simulationStep(input)))
.flatMap(_ => State.get) // `_ => xyz` creates a function that does not care about it's input
.map(machine => (machine.candies, machine.coins))
}
Note that the use of _ in _ => State.get is yet another way _ is used - now it creates a function that doesn't care about it's argument.
Now, answering questions as they are asked:
See above :)
If you look at desugared version, you'd see that the State.get is passed as a "callback" to flatMap. There are a few hoops to jump through to trace it (I'll leave it as an exercise for you :)), but essentially what it does is to replace the "result" part of the state (A) with the state itself (S)). Trick here is that it does not get the Machine at all - it just "chains" a call to "fetch" the Machine from the S part of state to A part of state.
I think desugared version should be pretty self-explanatory. Regarding the for-comprehension version - for fixes the "context" using the first call in the chain, so everything else (including yield) is executed in that "context" - specifically, it's fixed to State[_, _]. yield is essentially equivalent to calling map at the end of the chain, and in State[_, _] semantics, map replaces the A part, but preserves the S part.
Candy.simulateMachine(List(Coin, Turn, Coin, Turn)).run(Machine(false, 2, 0))
P.S. your current code still misses State.set method. I'm assuming it's just def set[S](s: => S): State[S, S] = State(_ => (s, s)) - at least adding this makes your snippet compile in my environment.
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.
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 :-)
I am new to Scala and try to focus on more functional programming
side of it.
I am trying to write a function filter.
Here is a definition and implementation:
def filter[A, B](f: A => Boolean, l: List[A]): List[B] = l match {
case Nil => List()
case x :: xs => if (f(x)) (x: B) :: filter(f, xs) else filter(f, xs)
}
Using this function, I get this error:
:32: error: type mismatch;
found : x.type (with underlying type A)
required: B
case x :: xs => if (f(x)) (x: B) :: filter(f, xs) else filter(f, xs)
Now, before that I wrote a function map:
def map[A, B](f: A => B, l: List[A]): List[B] = l match {
case Nil => List()
case x :: xs => f(x) :: map(f, xs)
}
that actually applies function f to convert each list element from type A to type B.
My error for filter seems to be caused by the fact that function taken by filter
does nothing to list element x of type A, so type checker thinks that I am still building a list of type A when B is required. You can see I tried to specify x as type B but it was in vain. Can anyone confirm that I understood problem correctly and how can I make x as type B? I could just return list of type A but
this is a function definition that is given as an exercise and I cannot change it.
Your filter method seems to try converting A to B which is not what filter methods usually do. A and B are two unrelated types, so you cannot cast between them
You would want something like that:
def filter[A](l: List[A])(f: A => Boolean): List[A] = l match {
case Nil => List()
case x :: xs => if (f(x)) x :: filter(xs)(f) else filter(xs)(f)
}
But you also can write this one a bit simpler:
def filter[A](l: List[A])(f: A => Boolean): List[A] =
for (x <- l if f(x)) yield x
Please also notice that I have swapped the arguments and divided them. This is done in order for scala's type inference to infer A automatically. Now you can do this:
filter(List(1, 3, 5, 7))(_ > 4)
where Int type is infered implicitly
Functional Programming in Scala defines Applicative#traverse as:
def traverse[A,B](as: List[A])(f: A => F[B]): F[List[B]]
as.foldRight(unit(List[B]()))((a, fbs) => map2(f(a), fbs)(_ :: _))
However, I implemented this function as:
def traverse[A,B](as: List[A])(f: A => F[B]): F[List[B]] =
as.foldRight(unit(List[B]()))((elem, acc) => map2(acc, f(elem))(_ :+ _))
With unit and map2 defined as:
def map2[A,B,C](fa: F[A], fb: F[B])(f: (A,B) => C): F[C]
def unit[A](a: => A): F[A]
As I understand my implementation, the map2(acc, f(elem))(_ :+ _)) will behave as so:
for each (element, accumulator), call map2(acc, f(elem)(_ :+ _))
to append the result of f(elem) (type F[B]) to the accumulator (type F[List[B]])
For my implementation, then, in the (f: (A,B) => C) part of traverse's map2 calls, List[B] appends B to itself.
map2 accepts arguments F[A] and F[B], but the function argument f operates on the A and B types. In the FP in Scala solution, B gets added to List[B] via the :: operator.
Is that right?
You are correct in your understanding of what is going on. Note, however, that your implementation will produce a list in the reverse order of what is expected, so if you used the identity monad as F, you'd get back a reversed list, instead of the same list.