Last active
August 24, 2016 12:56
-
-
Save fanf/6c45cb0cac28e6bd75c4204f59245a9a to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* | |
* Follow up of https://gist.github.com/fanf/845273a15377347a04375d51a0139b78 | |
* trying to use the new onionT1/onionT2/onionT3 from cats 0/6 | |
*/ | |
object Test1 { | |
type Maybe[A] = Xor[String, A] | |
final case class Query(value: String) | |
final case class Result(value: String) | |
sealed trait Backend { def search(q: Query): Maybe[List[Result]] } | |
/* final case object Backend1 extends Backend { | |
def search(q: Query) = Xor.right(List(Result("a"), Result("b"))) | |
} | |
final case object Backend2 extends Backend { | |
def search(q: Query) = Xor.right(List(Result("c"))) | |
} | |
final case object Backend3 extends Backend { | |
def search(q: Query) = Xor.left("This is a structured error message. Really. See: ponctuation.") | |
} | |
*/ | |
sealed trait MayFail1[A] | |
final object MayFail1 { | |
final case class Parse(query: String) extends MayFail1[Maybe[Query]] | |
} | |
sealed trait PureProcess[A] | |
final object PureProcess { | |
final case object MultiBackends extends PureProcess[List[Backend]] | |
} | |
sealed trait MayFail2[A] | |
final case object MayFail2 { | |
final case class GetMulti(query: Query, backends: List[Backend]) extends MayFail2[Maybe[List[Result]]] | |
} | |
type P = MayFail1 :|: MayFail2 :|: PureProcess :|: NilDSL | |
val P = DSL.Make[P] | |
type O2 = Maybe :&: List :&: Bulb | |
def search3(input: String): OnionT[Free, P.Cop, O2, List[Result]] = { | |
for { | |
query <- MayFail1.Parse(input) .freek[P].onionT[O2] | |
b <- PureProcess.MultiBackends .freek[P].onion[O2] | |
res <- MayFail2.GetMulti(query, b) .freek[P].onionT1[O2] // does not compile :( | |
} yield { | |
res | |
} | |
} | |
val a3: Free[P.Cop, Maybe[List[Result]]] = search3("plop").value | |
I started with that, but the returned type is not OK, we get too many Maybe in the end:
type O2 = Maybe :&: Bulb
def search3(input: String): OnionT[Free, P.Cop, O2, Maybe[List[Result]]] = {
for {
query <- MayFail1.Parse(input) .freek[P].onionT[O2]
b <- PureProcess.MultiBackends .freek[P].onion[O2]
res <- MayFail2.GetMulti(query, b) .freek[P].onion[O2]
} yield {
res
}
}
val a3: Free[P.Cop, Maybe[Maybe[List[Result]]]] = search3("plop").value
oh I had missed that GetMulti already contains the Maybe
...
so 3rd line should be onionT
Still not working, I think I tested that option to. The error is:
could not find implicit value for parameter lifter2: freek.Lifter2.Aux[cats.data.Xor[String,List[com.normation.rudder.services.quicksearch.Test1.Result]],com.normation.rudder.services.quicksearch.Test1.O2,com.normation.rudder.services.quicksearch.Test1.Result]
ok I see... it can't lift Maybe[List[Result]]]
to Maybe :&: Bulb
... there is nothing to do that...
For now, you can do:
import freek._
import cats.free.Free
import cats.data.Xor
import cats.instances.option._
import cats.instances.list._
/*
* Follow up of https://gist.github.com/fanf/845273a15377347a04375d51a0139b78
* trying to use the new onionT1/onionT2/onionT3 from cats 0/6
*/
object Test1 {
type Maybe[A] = Xor[String, A]
final case class Query(value: String)
final case class Result(value: String)
sealed trait Backend { def search(q: Query): Maybe[List[Result]] }
/* final case object Backend1 extends Backend {
def search(q: Query) = Xor.right(List(Result("a"), Result("b")))
}
final case object Backend2 extends Backend {
def search(q: Query) = Xor.right(List(Result("c")))
}
final case object Backend3 extends Backend {
def search(q: Query) = Xor.left("This is a structured error message. Really. See: ponctuation.")
}
*/
sealed trait MayFail1[A]
final object MayFail1 {
final case class Parse(query: String) extends MayFail1[Maybe[Query]]
}
sealed trait PureProcess[A]
final object PureProcess {
final case object MultiBackends extends PureProcess[List[Backend]]
}
sealed trait MayFail2[A]
final case object MayFail2 {
final case class GetMulti(query: Query, backends: List[Backend]) extends MayFail2[Maybe[List[Result]]]
}
type P = MayFail1 :|: MayFail2 :|: PureProcess :|: NilDSL
val P = DSL.Make[P]
type O2 = Maybe :&: Bulb
def search3(input: String): OnionT[Free, P.Cop, O2, List[Result]] = {
for {
query <- MayFail1.Parse(input) .freek[P].onionT[O2]
b <- PureProcess.MultiBackends .freek[P].onion[O2]
res <- MayFail2.GetMulti(query, b) .freek[P].onionT[Maybe :&: List :&: Bulb].peelRight
} yield {
res
}
}
val a3: Free[P.Cop, Maybe[List[Result]]] = search3("plop").value
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
it's normal that it doesn't compile
.onionT1
returns aOnionT[Free, P.Cop, Maybe :&: Bulb, List[Result]]
but other lines returnOnionT[Free, P.Cop, Maybe :&: List :&: Bulb, Result]
... so for-comprehension is broken as types are not the same on all lines... normal :)to me, your onion is
type O2 = Maybe :&: Bulb
and you must use.onion
on 2nd/3rd line