"call-cc" patterns in Scala? - scala

I found a good article, about call with current continuation patterns. As I understand, they use Scheme and undelimited continuations. Can the patterns from the article be implemented in Scala? Is there any article about delimited continuations patterns in Scala ?

Yes, they absolutely can. callCC looks like this in Scala:
def callCC[R, A, B](f: (A => Cont[R, B]) => Cont[R, A]): Cont[R, A] =
Cont(k => f(a => Cont(_ => k(a))) run k)
Where Cont is a data structure that captures a continuation:
case class Cont[R, A](run: (A => R) => R) {
def flatMap[B](f: A => Cont[R, B]): Cont[R, B] =
Cont(k => run(a => f(a) run k))
def map[B](f: A => B): Cont[R, B] =
Cont(k => run(a => k(f(a))))
}
Here's how you might use it to simulate checked exceptions:
def divExcpt[R](x: Int, y: Int, h: String => Cont[R, Int]): Cont[R, Int] =
callCC[R, Int, String](ok => for {
err <- callCC[R, String, Unit](notOK => for {
_ <- if (y == 0) notOK("Denominator 0") else Cont[R, Unit](_(()))
r <- ok(x / y)
} yield r)
r <- h(err)
} yield r)
You would call this function as follows:
scala> divExcpt(10, 2, error) run println
5
scala> divExcpt(10, 0, error) run println
java.lang.RuntimeException: Denominator 0

Scala has an implementation of typed delimited continuations which used to be shipped with the compiler and standard library, but has been extracted to an external module and pretty much left to rot since then. It's a great shame, and I encourage anyone who's interested in delimited continuations to show that they care about its existence by using and contributing to it.

Related

Programming a state monad in Scala

The theory of how a state monad looks like I borrow from Philip Wadler's Monads for Functional Programming:
type M a = State → (a, State)
type State = Int
unit :: a → M a
unit a = λx. (a, x)
(*) :: M a → (a → M b) → M b
m * k = λx.
let (a, y) = m x in
let (b, z) = k a y in
(b, z)
The way I would like to use a state monad is as follows:
Given a list L I want different parts of my code to get this list and update this list by adding new elements at its end.
I guess the above would be modified as:
type M = State → (List[Data], State)
type State = List[Data]
def unit(a: List[Data]) = (x: State) => (a,x)
def star(m: M, k: List[Data] => M): M = {
(x: M) =>
val (a,y) = m(x)
val (b,z) = k(a)(y)
(b,z)
}
def get = ???
def update = ???
How do I fill in the details, i.e.?
How do I instantiate my hierarchy to work on a concrete list?
How do I implement get and update in terms of the above?
Finally, how would I do this using Scala's syntax with flatMap and unit?
Your M is defined incorrectly. It should take a/A as a parameter, like so:
type M[A] = State => (A, State)
You've also missed that type parameter elsewhere.
unit should have a signature like this:
def unit[A](a: A): M[A]
star should have a signature like this:
def star[A, B](m: M[A], k: A => M[B]): M[B]
Hopefully, that makes the functions more clear.
Your implementation of unit was pretty much the same:
def unit[A](a: A): M[A] = x => (a, x)
However, in star, the parameter of your lambda (x) is of type State, not M, because M[B] is basically State => (A, State). The rest you got right:
def star[A, B](m: M[A])(k: A => M[B]): M[B] =
(x: State) => {
val (a, y) = m(x)
val (b, z) = k(a)(y)
(b, z)
}
Edit: According to #Luis Miguel Mejia Suarez:
It would probably be easier to implement if you make your State a class and define flatMap inside it. And you can define unit in the companion object.
He suggested final class State[S, A](val run: S => (A, S)), which would also allow you to use infix functions like >>=.
Another way to do it would be to define State as a type alias for a function S => (A, S) and extend it using an implicit class.
type State[S, A] = S => (A, S)
object State {
//This is basically "return"
def unit[S, A](a: A): State[S, A] = s => (a, s)
}
implicit class StateOps[S, A](private runState: S => (A, S)) {
//You can rename this to ">>=" or "flatMap"
def *[B](k: A => State[S, B]): State[S, B] = s => {
val (a, s2) = runState(s)
k(a)(s2)
}
}
If your definition of get is
set the result value to the state and leave the state unchanged
(borrowed from Haskell Wiki), then you can implement it like this:
def get[S]: State[S, S] = s => (s, s)
If you mean that you want to extract the state (in this case a List[Data]), you can use execState (define it in StateOps):
def execState(s: S): S = runState(s)._2
Here's a terrible example of how you can add elements to a List.
def addToList(n: Int)(list: List[Int]): ((), List[Int]) = ((), n :: list)
def fillList(n: Int): State[List[Int], ()] =
n match {
case 0 => s => ((), s)
case n => fillList(n - 1) * (_ => addToList(n))
}
println(fillList(10)(List.empty)) gives us this (the second element can be extracted with execState):
((),List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1))

Understanding Scala for comprehension in this example code

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.

compiler error message when using State monad for memoization

I have a problem to make a working version of the Euler project problem 31 with the use of State trait (inspired from scalaz)
First, I have a solution with a mutable HashMap for memoization. It works but i would like to use the State monad, to understand it and to improve my skills.
I have used it with the fibonacci example, but when i attempt to apply the same technique to my case, i have a compiler error that i don't understand.
I use this implementation for State :
trait State[S, A] {
val run: S => (S, A)
def apply(s: S): (S, A) = run(s)
def eval(s: S): A = run(s)._2
def map[B](f: A => B): State[S, B] =
State { s: S =>
val (s1, a) = run(s)
(s1, f(a))
}
def flatMap[B](f: A => State[S, B]): State[S, B] =
State { s: S =>
val (s1, a) = run(s)
f(a)(s1)
}
}
object State {
def apply[S, A](f: S => (S, A)): State[S, A] = new State[S, A] {
final val run = f
}
def init[S, A](a: A) = State { s: S => (s, a) }
def update[S, A](f: S => S): State[S, Unit] = State { s: S => (f(s), ()) }
def gets[S, A](f: S => A): State[S, A] = State { s: S => (s, f(s)) }
}
my attempt to use it is here :
val coins = List(1, 2, 5, 10, 20, 50, 100, 200)
type MemoKey = (List[Int], Int)
type MemoType = Map[MemoKey, Int]
def ways(listCoins: List[Int], amount: Int): Int = {
def ways_impl(coins: List[Int], sum: Int): State[MemoType, Int] = (coins, sum) match {
case (Nil, 0) => State.init(1)
case (Nil, _) => State.init(0)
case (c :: cs, _) =>
for {
memoed <- State.gets { m: MemoType => m.get((coins, sum)) }
res <- memoed match {
case Some(way) => State.init[MemoType, Int](way)
case None =>
(for {
i <- 0 to sum / c
r <- ways_impl(cs, sum - i * c)
_ <- State.update { m: MemoType => m + ((coins, sum) -> r) }
} yield r).sum
}
} yield res
}
ways_impl(listCoins, amount) eval (Map())
I have a compiler error at this line :
r <- ways_impl(cs, sum - i * c)
The compiler said :
type mismatch; found : State[MemoType,Int] (which expands to) State[scala.collection.immutable.Map[(List[Int], Int),Int],Int] required: scala.collection.GenTraversableOnce[?]
For information, here is my first version with mutable map :
import scala.collection.mutable._
val memo = HashMap[(List[Int], Int), Int]()
val coins = List(1, 2, 5, 10, 20, 50, 100, 200)
def memoWays(coins: List[Int], sum: Int): Int = {
memo.getOrElse((coins, sum), {
val y = ways(coins, sum)
memo += ((coins, sum) -> y)
y
})
}
// brute force method with memoization
def ways(coins: List[Int], sum: Int): Int = (coins, sum) match {
case (Nil, 0) => 1
case (Nil, _) => 0
case (c :: cs, n) =>
(for {
i <- 0 to n / c
r = memoWays(cs, n - i * c)
} yield r).sum
}
println(s"result=${Mesure(ways(coins, 200))}")
What does that error mean ? Why the compiler want a GenTraversableOnce instead of State ?
What kind of thing i don't understand on State monad ?
And, if i may, I have an optional question :
Is my way to memoize with State Monad, is a good choice, or my first implementation with mutable map is better anyway ?
The problem is that your for comprehension is attempting to flatMap two unrelated types: a Range and a State. You're going to have to refactor, although off the top of my head, it's not clear to me how you'll be able to leverage State in a simple way. I'd probably use an immutable Map for the memo, a List to represent the future iterations to be tried, and simple recursion to iterate.

Getting and setting state in scala

Here is some code from the Functional Programming in Scala book:
import State._
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 {
type Rand[A] = State[RNG, A]
def unit[S, A](a: A): State[S, A] =
State(s => (a, s))
// The idiomatic solution is expressed via foldRight
def sequenceViaFoldRight[S, A](sas: List[State[S, A]]): State[S, List[A]] =
sas.foldRight(unit[S, List[A]](List.empty[A]))((f, acc) => f.map2(acc)(_ :: _))
// This implementation uses a loop internally and is the same recursion
// pattern as a left fold. It is quite common with left folds to build
// up a list in reverse order, then reverse it at the end.
// (We could also use a collection.mutable.ListBuffer internally.)
def sequence[S, A](sas: List[State[S, A]]): State[S, List[A]] = {
def go(s: S, actions: List[State[S, A]], acc: List[A]): (List[A], S) =
actions match {
case Nil => (acc.reverse, s)
case h :: t => h.run(s) match {
case (a, s2) => go(s2, t, a :: acc)
}
}
State((s: S) => go(s, sas, List()))
}
// We can also write the loop using a left fold. This is tail recursive like the
// previous solution, but it reverses the list _before_ folding it instead of after.
// You might think that this is slower than the `foldRight` solution since it
// walks over the list twice, but it's actually faster! The `foldRight` solution
// technically has to also walk the list twice, since it has to unravel the call
// stack, not being tail recursive. And the call stack will be as tall as the list
// is long.
def sequenceViaFoldLeft[S, A](l: List[State[S, A]]): State[S, List[A]] =
l.reverse.foldLeft(unit[S, List[A]](List()))((acc, f) => f.map2(acc)(_ :: _))
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))
}
I have spent hours thinking about why the get and set methods look the way they do, but I just don't understand.
Could anyone enlighten me, please?
The key is on the 3rd line:
case class State[S, +A](run: S => (A, S))
The stateful computation is expressed with the run function. This function represent a transition from one state S to another state S. A is a value we could produce when moving from one state to the other.
Now, how can we take the state S out of the state-monad? We could make a transition that doesn't go to a different state and we materialise the state as A with the function s => (s, s):
def get[S]: State[S, S] = State(s => (s, s))
How to set the state? All we need is a function that goes to a state s: ??? => (???, s):
def set[S](s: S): State[S, Unit] = State(_ => ((), s))
EDIT I would like to add an example to see get and set in action:
val statefullComputationsCombined = for {
a <- State.get[Int]
b <- State.set(10)
c <- State.get[Int]
d <- State.set(100)
e <- State.get[Int]
} yield (a, c, e)
Without looking further down this answer, what is the type of statefullComputationsCombined?
Must be a State[S, A] right? S is of type Int but what is A? Because we are yielding (a, c, e) must be a 3-tuple made by the As of the flatmap steps (<-).
We said that get "fill" A with the state S so the a, c ,d are of type S, so Int. b, d are Unit because def set[S](s: S): State[S, Unit].
val statefullComputationsCombined: State[Int, (Int, Int, Int)] = for ...
To use statefullComputationsCombined we need to run it:
statefullComputationsCombined.run(1)._1 == (1,10,100)
If we want the state at the end of the computation:
statefullComputationsCombined.run(1)._2 == 100

Implementing foldLeft on IndexedSeq

As part of an exercise from FP in Scala, I'm working on the implementation of foldLeft on an IndexedSeq.
I wrote 2 functions:
def foldLeft[A, B](as: IndexedSeq[A])(z: B)(f: (B, A) => B): B = {
def go(bs: IndexedSeq[A], acc: B): B = {
if (bs.isEmpty) acc
else go(bs.tail, f(acc, bs.head))
}
go(as, z)
}
And, then the pattern match way:
def foldLeftPM[A, B](as: IndexedSeq[A])(z: B)(f: (B, A) => B): B = {
def go(bs: IndexedSeq[A], acc: B): B = bs match {
case x +: xs => go(xs, f(acc, x))
case _ => acc
}
go(as, z)
}
EDIT Note that I got the +: operator from dhgs's answer. It appears to be a member of IndexedSeq's class or its parent since it's available without defining per the linked post.
Is either way better (from a performance or idiomatic Scala point of view)?
The pattern match is definitely more idiomatic.
For performance, they should be about the same, since they are exactly equivalent.
Though only benchmarking would decide, and that includes a lot of assumptions.