0

i try to transform this code into the CPS form:

   def sum ( lst :  List [ Int ]) :  Int  =  lst match {
     case Nil => 0
     case first :: rest => first  +  sum ( rest )
   }


  def sumC1(lst :  List [ Int ], k :  Int => Unit ) :  Unit  =  lst match {
     case lst => k(sum(lst))
   }

I ma new to scala and got very big problems undertand the syntax. it would be very helpful if you give me some syntax to solve this task

Here is my code with a typ mismatch:

  def sum(lst: List[Int])(cont: Int => Int): Int = lst match {
    case Nil => cont(0)
    case first :: rest => sum(lst){rest => cont(first + rest) }
  }

  def sumC1(lst: List[Int], k: Int => Unit): Unit = lst match {
    case lst => k(sum(lst))
  }
  sumC1(List(1, 2, 3), (v: Int) => println(v))

1 Answers1

0

A much more simple approach to do that

def sum(lst: List[Int]): Int =
    lst.foldLeft(0){
      case(cont, i) => cont +i
    }
def sumC1(lst: List[Int], k: Int => Unit): Unit = 
    k(sum(lst))

This can be written in this other way

def sum(lst: List[Int]): Int =
    lst.foldLeft(0)(_ + _)
def sumC1(lst: List[Int], k: Int => Unit): Unit = 
    k(sum(lst))

foldLeft method pass the counter in each step for you.

The simplest way to do this is

def sumC1(lst: List[Int], k: Int => Unit): Unit = 
    k(lst.sum)

or

def sum(lst: List[Int]): Int =
    lst.fold(0)(_ + _)
def sumC1(lst: List[Int], k: Int => Unit): Unit = 
    k(sum(lst))

EDIT: building the computation

def sum(lst: List[Int]): Int =
    lst.foldLeft[ Int => Int](v => v){
      case(cont, i) =>  v => v + cont(i)
    }(0)

def sumC1(lst: List[Int], k: Int => Unit): Unit =
    k(sum(lst))

or

def sum(lst: List[Int]): Int =
    lst.foldLeft[ Unit => Int](Unit => 0){
      case(cont, i) =>  Unit => i + cont()
    }()

def sumC1(lst: List[Int], k: Int => Unit): Unit =
    k(sum(lst))
Mikel San Vicente
  • 3,831
  • 2
  • 21
  • 39
  • This answer defeats the purpose of the exercise, you're supposed to thread the continuation through the entire computation. – Lee Feb 12 '17 at 18:26
  • The first snippet is exactly doing the continuation passing – Mikel San Vicente Feb 12 '17 at 18:30
  • Your first snippet doesn't compile since `cont` isn't defined anywhere. If it were, it would have type `Int => Unit` so `cont + i` wouldn't type check. You're just calculating the sum directly and then passing it to the continuation, not using it througout the sum process. – Lee Feb 12 '17 at 18:36
  • cont is the first parameter of the partial function passed to the foldLeft, it's of type Int, copy and paste the code to a Scala console and you will see that it compiles... – Mikel San Vicente Feb 12 '17 at 18:38
  • The whole point is that `cont` is supposed to be a function representing the rest of the computation. In the OP is has type `Int => Unit`, you can't just change it to `Int`. – Lee Feb 12 '17 at 18:39
  • if we want to build the computation I think it make more sense to use Unit =>Int, I have added a possible solution – Mikel San Vicente Feb 12 '17 at 18:54
  • The issue with this last approach is that can throw a StackOverflowError when the list is too big – Mikel San Vicente Feb 12 '17 at 19:05
  • The continuation is the parameter `k` in `sumC1` in the OP and has type `Int => Unit`. It should receive the result of calculating the sum of the list. To rewrite in CPS each recursive call needs to build a larger continuation which invokes the original continuation with the sum of the result from the recursive call and the current element. – Lee Feb 12 '17 at 19:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135522/discussion-between-mikel-and-lee). – Mikel San Vicente Feb 12 '17 at 19:49