-
-
Save fanf/f26eee67ae33bf54e363e4e5dce01388 to your computer and use it in GitHub Desktop.
| object FreekQuickSearch { | |
| import cats.free.Free | |
| import cats.data.Xor | |
| import freek._ | |
| final case class Wrong(message: String, cause: Option[Throwable] = None) | |
| type Maybe[A] = Xor[Wrong, A] | |
| /// | |
| /// Domain: a parser, a log, a backend processing query | |
| /// | |
| final case class Result(value: String) | |
| // log | |
| sealed trait Log[A] | |
| object Log { | |
| final case class DebugMsg(msg: String) extends Log[Unit] | |
| } | |
| /// parser | |
| sealed trait Parser[A] | |
| object Parser { | |
| final case class Parse(input: String) extends Parser[Maybe[Query]] | |
| } | |
| /// backend processing | |
| sealed trait Backend[A] | |
| object Backend { | |
| final case class Search(query: Query) extends Backend[Maybe[Seq[Result]]] | |
| } | |
| type PRG = Parser :|: Log :|: Backend :|: FXNil | |
| val PRG = Program[PRG] | |
| type O = Maybe :&: Bulb | |
| /// parse user input, log query, process query | |
| def search(input: String) = { | |
| for { | |
| query <- Parser.Parse(input).freeko[PRG, O] // error 1 | |
| _ <- Log.DebugMsg(s"User query for '${input}', parsed as user query: '${query.userToken}' on objects: " + | |
| s"'${query.objectClass.mkString(", ")}' and attributes '${query.attributes.mkString(", ")}'" | |
| ).freeko[PRG, O] | |
| results <- Backend.Search(query).freeko[PRG, O] // error 2 | |
| } yield { | |
| results | |
| } | |
| } | |
| } | |
| /* | |
| 1: | |
| type mismatch; found : | |
| com.normation.rudder.services.quicksearch.Query => freek.OnionT[cats.free.Free,[t(in type Cop)]freek. | |
| In3[com.normation.rudder.services.quicksearch.FreekQuickSearch.Parser,com.normation. | |
| rudder.services.quicksearch.FreekQuickSearch.Log,com.normation.rudder.services.quicksearch.FreekQuickSearch. | |
| Backend,t(in type Cop)],freek.:&:[[A]cats.data.Xor[com.normation.rudder.services.quicksearch.FreekQuickSearch. | |
| Wrong,A],freek.Bulb], | |
| Nothing] | |
| required: | |
| com.normation.rudder.services.quicksearch.Query => freek.OnionT[cats.free.Free,[t(in type Cop)]freek. | |
| In3[com.normation.rudder.services.quicksearch.FreekQuickSearch.Parser,com.normation. | |
| rudder.services.quicksearch.FreekQuickSearch.Log,com.normation.rudder.services.quicksearch.FreekQuickSearch. | |
| Backend,t(in type Cop)],freek.:&:[[A]cats.data.Xor[com.normation.rudder.services.quicksearch.FreekQuickSearch. | |
| Wrong,A],freek.Bulb], | |
| B] | |
| 2: | |
| could not find implicit value for parameter lifter2: | |
| freek.Lifter2.Aux[com.normation.rudder.services.quicksearch.FreekQuickSearch.Maybe[Seq[com.normation.rudder.services. | |
| quicksearch.FreekQuickSearch.Result]],com.normation.rudder.services.quicksearch.FreekQuickSearch.O,A] | |
| not enough arguments for method freeko: (implicit ga: freek.HKK.Aux[com.normation.rudder.services.quicksearch. | |
| FreekQuickSearch.Maybe[Seq[com.normation.rudder.services.quicksearch.FreekQuickSearch.Result]],com.normation.rudder. | |
| services.quicksearch.FreekQuickSearch.Result], implicit subfx: freek.SubFX[[β]freek.In1[com.normation.rudder.services. | |
| quicksearch.FreekQuickSearch.Backend,β],com.normation.rudder.services.quicksearch. | |
| FreekQuickSearch.PRG], implicit lifter2: freek.Lifter2.Aux[com.normation.rudder.services.quicksearch.FreekQuickSearch. | |
| Maybe[Seq[com.normation.rudder.services.quicksearch.FreekQuickSearch.Result]],com.normation.rudder.services.quicksearch. | |
| FreekQuickSearch.O,com.normation.rudder.services.quicksearch.FreekQuickSearch.Result], implicit pointer: freek. | |
| Pointer[com.normation.rudder.services.quicksearch.FreekQuickSearch.O], implicit mapper: freek.Mapper[com.normation.rudder. | |
| services.quicksearch.FreekQuickSearch.O], implicit binder: freek.Binder[com.normation.rudder.services.quicksearch. | |
| FreekQuickSearch.O], implicit traverser: freek.Traverser[com.normation.rudder.services.quicksearch.FreekQuickSearch.O])freek. | |
| OnionT[cats.free.Free,subfx.Cop,com.normation.rudder.services.quicksearch.FreekQuickSearch.O,com.normation.rudder.services. | |
| quicksearch.FreekQuickSearch.Result]. Unspecified value parameters lifter2, pointer, mapper... | |
| */ |
mandubian
commented
Aug 1, 2016
Thanks, it works, and thanks for the nice explanation.
Have you activated special error reporting options?
The error is simply:
could not find implicit value for parameter lifter2: freek.Lifter2.Aux[com.normation.rudder.services.quicksearch.FreekQuickSearch.Maybe[Seq[com.normation.rudder.services. quicksearch.FreekQuickSearch.Result]],com.normation.rudder.services.quicksearch.FreekQuickSearch.O,A]
just can't lift that to O which seems not so normal but which is linked to my current implementation based on implicit conversion to add freeko...
object FreekQuickSearch {
// import cats.free.Free
// import cats.data.Xor
// import freek._
case class Query(userToken: String, objectClass: List[String], attributes: List[String])
final case class Wrong(message: String, cause: Option[Throwable] = None)
type Maybe[A] = Xor[Wrong, A]
///
/// Domain: a parser, a log, a backend processing query
///
final case class Result(value: String)
// log
sealed trait Log[A]
object Log {
final case class DebugMsg(msg: String) extends Log[Unit]
}
/// parser
sealed trait Parser[A]
object Parser {
final case class Parse(input: String) extends Parser[Maybe[Query]]
}
/// backend processing
sealed trait Backend[A]
object Backend {
final case class Search(query: Query) extends Backend[Maybe[List[Result]]]
}
type PRG = Parser :|: Log :|: Backend :|: FXNil
val PRG = Program[PRG]
type O = Maybe :&: List :&: Bulb
/// parse user input, log query, process query
def search(input: String) = {
for {
query <- Parser.Parse(input).freeko[PRG, O] // error 1
_ <- Log.DebugMsg(s"User query for '${input}', parsed as user query: '${query.userToken}' on objects: " +
s"'${query.objectClass.mkString(", ")}' and attributes '${query.attributes.mkString(", ")}'"
).freeko[PRG, O]
// here you can't use freeko due to limitations of implicits conversion...
// once an implicit convention has been chosen, it doesn't backdrack...
// I've chosen (by convention) to make freeko take by default the deeper stack to resolve the onion O in freeko...
// In your case, it searches `Maybe :&: Seq` in the Onion and fails as expected but doesn't try other solutions...
// For this case, I have this onionP function that stops at first layer...
// Maybe we could do better but haven't found solution yet...
results <- Backend.Search(query).freeko[PRG, O] // error 2
} yield {
results
}
}
}
FreekQuickSearch.search("toto")
}object FreekQuickSearch {
// import cats.free.Free
// import cats.data.Xor
// import freek._
case class Query(userToken: String, objectClass: List[String], attributes: List[String])
final case class Wrong(message: String, cause: Option[Throwable] = None)
type Maybe[A] = Xor[Wrong, A]
///
/// Domain: a parser, a log, a backend processing query
///
final case class Result(value: String)
// log
sealed trait Log[A]
object Log {
final case class DebugMsg(msg: String) extends Log[Unit]
}
/// parser
sealed trait Parser[A]
object Parser {
final case class Parse(input: String) extends Parser[Maybe[Query]]
}
/// backend processing
sealed trait Backend[A]
object Backend {
final case class Search(query: Query) extends Backend[Maybe[List[Result]]]
}
type PRG = Parser :|: Log :|: Backend :|: FXNil
val PRG = Program[PRG]
type O = Maybe :&: List :&: Bulb
/// parse user input, log query, process query
def search(input: String) = {
for {
lquery <- Parser.Parse(input).freeko[PRG, O].peelRight // error 1
List(query) = lquery
_ <- Log.DebugMsg(s"User query for '${input}', parsed as user query: '${query.userToken}' on objects: " +
s"'${query.objectClass.mkString(", ")}' and attributes '${query.attributes.mkString(", ")}'"
).freeko[PRG, O].peelRight
// here you can't use freeko due to limitations of implicits conversion...
// once an implicit convention has been chosen, it doesn't backdrack...
// I've chosen (by convention) to make freeko take by default the deeper stack to resolve the onion O in freeko...
// In your case, it searches `Maybe :&: Seq` in the Onion and fails as expected but doesn't try other solutions...
// For this case, I have this onionP function that stops at first layer...
// Maybe we could do better but haven't found solution yet...
results <- Backend.Search(query).freeko[PRG, O].peelRight // error 2
} yield {
results
}
}
}
FreekQuickSearch.search("toto")
}@mandubian
The last one seems to be the only one giving a Vector[Result] - which is the expected type.
The other two are returning a Xor[..., Vector[Result]], certainly because they only go one frame deep in the stack (but we would like them to go two frames deep, or perhaps "keep only the last K frames". You don't have something like that in Freek, it seems I always need it :/