aboutsummaryrefslogtreecommitdiff
path: root/core/lib/FiberConversions.scala
blob: fe79796bcbe3d133fecea2dbebc3d7c805e16018 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package eu.mulk.fibers

import scala.collection.generic.CanBuildFrom
import scala.collection.{GenTraversableOnce, IterableLike}
import scala.language.implicitConversions

/**
  * Implicit conversions for convenient use of containers from within
  * fibers.
  */
private[fibers] trait FiberConversions extends FiberTypes {
  //
  // This is based on code by James Earl Dougles, taken from:
  //
  //     https://earldouglas.com/posts/monadic-continuations.html
  //

  /**
    * Defines the `cps` helper on [[IterableLike]] objects, which you can call to
    * traverse them from fibers.
    */
  implicit def cpsIterable[A, Repr](xs: IterableLike[A, Repr]) = new {

    /**
      * Provides fiber-compatible iteration functions.
      */
    def cps = new {
      def foreach[B, T](f: A => Any @fiber[T]): Unit @fiber[T] = {
        val it = xs.iterator
        while (it.hasNext) f(it.next)
      }
      def map[B, That, T](f: A => B @fiber[T])(
          implicit cbf: CanBuildFrom[Repr, B, That]): That @fiber[T] = {
        val b = cbf(xs.repr)
        foreach(b += f(_))
        b.result
      }
      def flatMap[B, That, T](f: A => GenTraversableOnce[B] @fiber[T])(
          implicit cbf: CanBuildFrom[Repr, B, That]): That @fiber[T] = {
        val b = cbf(xs.repr)
        for (x <- this) b ++= f(x)
        b.result
      }
    }
  }
}