Search code examples
scalascalazscalaz-stream

Using Scalaz stream, how to convert A => Task[B] to Process1[A,B]


I am encoding a http request to a remote server as a function which takes an id and yields a Task[JValue].

I would like to convert that function into a Process1, to simplify my program (By simplify, i mean use Processes as building blocks as much as possible)

I would like to convert the function

    reqDoc(id:A):Task[B]

(where A is the type of the Id, and B is the type of the response) into

    reqDoc:Process1[A,B]

Solution

  • I don't think you want a Process1, I think that if you were creating a Process1 out of this you would be creating a Process1[A, Task[B]] which isn't what you want.

    I think you want to create a Channel that you can attach a Process to that would give you a new Process. A Channel is just an alias for a Process that produces effectful functions.

    type Channel[+F[_],-I,O] = Process[F, I => F[O]]
    

    Since you have one function, you are just going to create a process which produces an infinite stream of the same function, which constant

    // a String => Task[Int] that we'll make a channel from
    val length: String => Task[Int] = (x => Task.delay(x.length))
    // a channel is just a source of functions:
    val lengthChannel = Process.constant(length)
    

    Now given a Process that produces Strings (here we'll produce just one):

    val source: Process[Task,String] = Process.emit("asdf")
    

    We can create a process by running our source through our channel

    val lengths = source through lengthChannel
    

    and we can run our process and get the length of "asdf"

    scala> lengths.runLog.run
    res5: scala.collection.immutable.IndexedSeq[Int] = Vector(4)