zcbzfl
zcbzfl

Reputation: 113

<Functional Programing in Scala> simulateMachine

Exercise 13

The official answer is:

  def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
    _ <- sequence(inputs map (modify[Machine] _ compose update))
    s <- get
  } yield (s.coins, s.candies)

the position of the second placeholder in the second line really confuses me, the right answer from my perspective should be this:

  def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
    _ <- sequence(inputs map ((modify[Machine] compose update) _))
    s <- get
  } yield (s.coins, s.candies)

please help me understand why the first answer is right, thanks very much

Upvotes: 1

Views: 194

Answers (3)

Mouna
Mouna

Reputation: 3359

modify is a method, we must convert it to a function to be able to use compose. The way we do this in scala is by using placeholder syntax or by using eta expansion.

(modify[Machine] _) is equivalent to (f => modify[Machine](f))

So another way to write this is:

def modifyFunction: ((Machine => Machine)) => State[Machine, Unit] = f => modify[Machine](f)

def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
    _ <- sequence(inputs map (modifyFunction compose update))
    s <- get
} yield (s.coins, s.candies)

Upvotes: 0

Emiliano Martinez
Emiliano Martinez

Reputation: 4133

The question here is how actually compose works: "compose makes a new function that composes other functions f(g(x))", f compose g can be translated to: "execute f after g"

scala> val fComposeG = f _ compose g _
fComposeG: (String) => java.lang.String = <function>

This composition returns another function which accepts an Input and return a new State[A, S].

The compiler lets you to make something like that:

val ll = inputs map update

Now ll is a List[Machine => Machine] which is exactly what update function needs. After modify it´s necessary the underscore, otherwise the compiler alerts "missing argument list for method modify...."

Upvotes: 1

Odomontois
Odomontois

Reputation: 16328

modify, I believe, is some known method, so placeholder is just an eta expansion in of the method, converting it to the Function1 and enabling using of its methods like compose

So without placeholder after modify[Machine] in modify[Machine] compose update there may be compile error sometimes. But if there is not, then no need for placeholder after full expression either, because it's guaranteed that result of compose is a Function1 and could be use as parameter for map

Upvotes: 3

Related Questions