ProjectSeptemberInc / freek

Freek, a freaky simple Free to combine your DSL seamlessly
Other
198 stars 19 forks source link

newbie question #7

Open bhericher opened 8 years ago

bhericher commented 8 years ago

This looks very interesting, but considering your example AppSpec, I come in trouble at lines 177-192 :

def handle(req: HttpReq): Free[PRG#Cop, HttpResp] = req.url match { case "/foo" => for { _ <- Log.debug("/foo").freek[PRG] dbRes <- DBService.findById("foo").expand[PRG]

        resp  <-  HttpHandle.result(
                    dbRes match {
                      case Xor.Left(err) => HttpResp(status = InternalServerError)
                      case Xor.Right(e)   => HttpResp(status = Ok, body = e.toString)
                    }
                  ).freek[PRG]
      } yield (resp)

    case _ => HttpHandle.result(HttpResp(status = InternalServerError)).freek[PRG]

}

with "classical monads", one would expect that if dbRes is xor.Left, the call to httpHandle.result doesn't occur, but it's clearly not the case : we don't exit from the for-comprehension. How would you product the same behavior with Freek?

Hope my english is not too bad...

Thank you

Benoit

yilinwei commented 8 years ago

@bhericher

One way which I've done this when working with free monads is to introduce a type which terminates in the DSL such as case class Terminate(t: Throwable) extends DSL[Nothing].

In this case, you force the natural transformation for this DSL to deal with it - basically you have to have a transformation from DSL ~> Throwable Xor ? rather than the typical DSL ~> Id.