iniyanp
2/13/2017 - 4:36 AM

Signal get interpreter

Signal get interpreter

package exercise
import java.util.concurrent.{ExecutorService, Executors, ThreadFactory}

import exercise.MyOp.{GetName}

import scalaz.concurrent.{Strategy, Task}
import scalaz.stream.async
import scalaz.Scalaz._
import scalaz._
import scalaz.stream._
import scalaz.stream.async.mutable.Signal
import scalaz.stream.async.mutable.Signal.Msg
import tortuga.Free

/**
  * Created by paramin on 2/6/17.
  */




sealed trait MyOp[A] extends Product with Serializable

object MyOp{
  final case class GetName() extends MyOp[Unit]
}

class FreeUtil[F[_]](implicit I: Inject[MyOp, F]) {
  def getName(): Free[F, Unit] = {
    Free.inject[MyOp, F](GetName())
  }
}



object FreeUtil {
  implicit def freeUtilInstance[F[_]](implicit T: Inject[MyOp, F]): FreeUtil[F] = new FreeUtil[F]
}


object exercise20 {

  val p:Process[Task, String] = Process.emitAll(List("Iniyan","Preethi","Thamarai","Kumar")).toSource

  type CombinerAppF[A] = Free[MyOp, A]

  def testMethod()(implicit U:FreeUtil[MyOp]):CombinerAppF[Unit] = {
    import U._
    for{
      now <- U.getName()
    }yield()
  }

  def main(args: Array[String]): Unit = {

    val myOpInterpreter = new (MyOp ~> (String => ?)){
      override def apply[A](fa: MyOp[A]): (String) => A = fa match {

        case GetName() => {
          name => {
            println(s"My name is ${name} ... :)")
          }
        }
      }
    }

    val signalProcess:Process[Task, MyOp ~> Task] = Process.bracket(Task.delay(async.signalUnset[String](Strategy.DefaultStrategy)))(signal =>
      Process.eval_(Task.delay(println("Signal is closed.")) *> signal.close)){
      signal => {
        val func:String => Msg[String] = s => async.mutable.Signal.Set(s)
//        createThread(signal.discrete)
        val sink = signal.sink.contramap(func)

        val bgProcesses: Process[Task, Unit] =
          Process.eval_(
            Task.delay(
              println("Starting background processing of guide events"))).append(p to sink)

        val myInterpreter = new (MyOp ~> Task) {
          override def apply[A](fa: MyOp[A]): Task[A] = {
            signal.get.map(name => myOpInterpreter(fa)(name))
          }
        }
        bgProcesses.run.run
        val res = Process.emit(myInterpreter)
        res
      }
    }

    val result = signalProcess.map{

      interpreter => {
        testMethod().foldMap(interpreter).run
      }
    }

    result.run.run 
    //Starting background processing of guide events
    //My name is Kumar ... :)
    //Signal is closed.
  }
}