Created
June 5, 2016 20:58
-
-
Save pvillega/21ab35b67c3b903d84cdf6136391e1b3 to your computer and use it in GitHub Desktop.
Can we merge the interpreters?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// simplified code to give the idea. Starting with 2 DSL, Trades and Http | |
object Trades { | |
sealed trait DSL[A] { def url: String } | |
final case class HeartBeat() extends DSL[TradeResult[StatusOk]] | |
type TradesPRG[A] = (DSL :|: FXNil)#Cop[A] | |
} | |
object Http { | |
sealed trait DSL[A] | |
final case class Get(url: String, parameters: Map[String, List[String]]) extends DSL[Result] | |
type HttpPRG[A] = (DSL :|: FXNil)#Cop[A] | |
val executerInterpreter: Interpreter[HttpPRG, Task] = AsyncHttpInterpreter | |
// I need this alias for interpreters, see comments below | |
type HttpFree[A] = Free[HttpPRG, A] | |
} | |
// Now we define an interpreter from Http to AsyncHttp (some code omitted for brevity) | |
object AsyncHttpInterpreter extends (Http.DSL ~> Task) { | |
import Http._ | |
def apply[A](a: Http.DSL[A]) = a match { | |
case Get(url, parameters) => get(url, parameters) | |
} | |
} | |
// It seems I can't create an interpreter from Trades.DSL to Http.DSL, instead I need to go from Trades.DSL to Http.HttpFree | |
object TradesHttpInterpreter extends (Trades.DSL ~> Http.HttpFree) { | |
import Trades._ | |
import Http._ | |
def apply[A](a: Trades.DSL[A]) = a match { | |
case o @ HeartBeat() => | |
val x: Free[HttpPRG, Result] = for { | |
rsp <- Get(o.url, Map.empty[String, List[String]]).freek[HttpPRG] | |
} yield rsp | |
x.map(rslt => StatusOk().asInstanceOf[A].right) | |
} | |
} | |
// To run a program them it seems I can't combine the interpreters I have, but I need to run 2 foldmap in a row | |
// (compile fails when trying to compose them) | |
localProgram | |
.foldMap(TradesHttpInterpreter.nat).foldMap(Http.executerInterpreter.nat) | |
.runAsync | |
// Is there any way to combine TradesHttpInterpreter and Http.executerInterpreter in a single interpreter? |
My only question (may be a misunderstanding on my part), if I do Trades.DSL ~> HTTP.DSL
then how do I work with the Results of Http.DSL
?
So if I want to define an operation HeartBeat()
from Trades.DSL
as a GET
+ parsing the return json to an object HeartbeatResult
, how do I define that? Won't I need the HttpFree
for that?
it certainly means you want to :
1/ convert result of Http to TradesResult : Trades.DSL ~> Http.DSL ~> TradesResult.DSL
2/ combine Trades.DSL & Http.DSL in your program as a Coproduct Trades.DSL :|: Http.DSL
yes, I see, I was doing it the wrong way around, thanks! you helped a lot! :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ok I catch what you want to do... you want to "lift" all DSL to HTTP and then do calls and finally get results...
But I don't understand why you can't write
Trades.DSL ~> HTTP.DSL
because your
Trades.DSL ~> Http.HttpFree
isn't necessarily bad but it smells likeTrades.DSL ~> HTTP.DSL
would be more logical or I miss something ;)