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? |
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
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 ofHttp.DSL
?So if I want to define an operation
HeartBeat()
fromTrades.DSL
as aGET
+ parsing the return json to an objectHeartbeatResult
, how do I define that? Won't I need theHttpFree
for that?