Reputation: 113
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
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
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
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