scala - Continuations and for comprehensions -- what's the incompatibility? -



scala - Continuations and for comprehensions -- what's the incompatibility? -

i new scala , trying wrap head around continuations i'm trying reproduce yield return c# statement.

following this post, have written next code :

package com.company.scalatest import scala.util.continuations._; object gentest { val gen = new generator[int] { def produce = { yieldvalue(1) yieldvalue(2) yieldvalue(3) yieldvalue(42) } } // not compile :( // val gen2 = new generator[int] { // def produce = { // var ints = list(1, 2, 3, 42); // // ints.foreach((theint) => yieldvalue(theint)); // } // } // works? val gen3 = new generator[int] { def produce = { var ints = list(1, 2, 3, 42); var = 0; while (i < ints.length) { yieldvalue(ints(i)); = + 1; } } } def main(args: array[string]): unit = { gen.foreach(println); // gen2.foreach(println); gen3.foreach(println); } } abstract class generator[e] { var loopfn: (e => unit) = null def produce(): unit @cps[unit] def foreach(f: => (e => unit)): unit = { loopfn = f reset[unit, unit](produce) } def yieldvalue(value: e) = shift { genk: (unit => unit) => loopfn(value) genk(()) () } }

as can see, gen2 commented out not compile. since can iterate on content of list using while loop (see gen3), expected foreach loop work well.

the compilation error next :

no type parameters method foreach: (f: int => b)unit exist can applied arguments (int => unit @scala.util.continuations.cpsparam[unit,unit]) --- because --- argument expression's type not compatible formal parameter type; found : int => unit @scala.util.continuations.cpsparam[unit,unit] required: int => ?b

why error , there way work around cleaner while loop?

thank you

first let's @ take gen2 compile.

object cpsconversions { import scala.collection.iterablelike import scala.util.continuations._ implicit def cpsiterable[a, repr](xs: iterablelike[a, repr]) = new { def cps = new { def foreach[b](f: => any@cpsparam[unit, unit]): unit@cpsparam[unit, unit] = { val = xs.iterator while(it.hasnext) f(it.next) } } } } object gentest { import cpsconversions.cpsiterable val gen2 = new generator[int] { def produce = { var ints = list(1, 2, 3, 42) ints.cps.foreach((theint) => yieldvalue(theint)) } }

now let's take @ what's going on. original gen2 fails compile on next line:

ints.foreach((theint) => yieldvalue(theint))

since type of yieldvalue includes @cpsparam annotation, continuations plugin transforms function passed foreach method 1 of type:

int => unit @cpsparam[unit,unit]

way in hierarchy of list[int], you'll see foreach defined as:

foreach [u] (f: (int) ⇒ u): unit

this problem, types not match , scala doesn't know how int => u int => unit @cpsparam[unit,unit]. prepare it, added cps version of foreach in implicit conversion, can access calling cps on iterablelike.

it nice if implicit conversion done without explicit cps call, have not found way create scala compiler recognize applicability of such implicit conversion pimp new foreach onto list. might have order in compiler uses continuations plugin, know far little process sure.

so that's , foreach. question mentions comprehensions, require of filter, map, or flatmap defined (depending on goes on in comprehension). have implemented these in link in above comment, extends cpsconversions object above allow general comprehensions.

scala generator yield continuations continuation-passing

Comments

Popular posts from this blog

How do I check if an insert was successful with MySQLdb in Python? -

delphi - blogger via idHTTP : error 400 bad request -

postgresql - ERROR: operator is not unique: unknown + unknown -