iniyanp
6/14/2017 - 10:29 PM

sequence from Vincent

sequence from Vincent

object Test {
  import scalaz.\/
  import scala.concurrent.{ExecutionContext, Await, Future}
  import scala.concurrent.duration._
  import scala.concurrent.ExecutionContext.Implicits.global
  import scalaz.syntax.std.option._

  def flipOption[A](l: List[Option[A]]): Option[List[A]] =
    l.foldLeft(List[A]().some)
      ((accumulator: Option[List[A]], optiona: Option[A]) => accumulator.flatMap((la: List[A]) => optiona.map((a: A) => a :: la)))

  def flipFuture[A](l: List[Future[A]]): Future[List[A]] =
    l.foldLeft(Future { List[A]() })((accumulator: Future[List[A]], optiona: Future[A]) => accumulator.flatMap((la: List[A]) => future.map((a: A) => a :: la)))

  def flipGeneric[F[_], A](l: List[F[A]])(implicit TC: Bindable[F]): F[List[A]] = {
    l.foldLeft( TC.point(List[A]()) )((acc: F[List[A]], fa: F[A]) => TC.bind(acc)((la: List[A]) => TC.mymap(fa)((a: A) => a :: la)))
  }



  //Future definition is Future[A]  Monad
  implicit def futureBindable[A]: Bindable[Future] = new Bindable[Future] {
    override def bind[A, B](fa: Future[A])(f: A => Future[B]): Future[B] = fa.flatMap(f)
    override def mymap[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f)
    override def point[A](a: A): Future[A] = Future { a }
  }                    
  
  trait Bindable[F[_]] {
    def bind[A, B](fa: F[A])(f: A => F[B]): F[B]  
    def mymap[A, B](fa: F[A])(f: A => B): F[B] 
    def point[A](a: A): F[A]
  } 
}