Thank you in advance for your help
I have 2 functions that I am trying to compose via Kleisli arrows. The functions accept String and produce FreeC. The kleisli arrows are created without an issue but the compiler is complaining that it cannot find. I will cut out some of the code for simplicity:
import scalaz._
import Scalaz._
import Free.FreeC
import Free._
import Kleisli._
trait AppCompose {
def lift[F[_], G[_], A](fa: F[A])(implicit I: Inject[F, G]): FreeC[G, A] =
Free.liftFC(I.inj(fa))
}
object BigBrother {
sealed trait Sensor[A]
case class Log(log: String) extends Sensor[Unit]
case class Filter(log: String) extends Sensor[String]
case class Secure(log: String) extends Sensor[String]
}
import BigBrother.Sensor
class BigBrother[F[_]](implicit I: Inject[Sensor,F]) extends AppCompose {
import BigBrother._
type FreeString[A] = FreeC[F,String]
def log(log: String) = lift(Log(log))
def filter(log: String) = lift(Filter(log))
def secure(log: String) = lift(Secure(log))
def filterAndSecure(phrase: String) = for {
f <- filter(phrase)
s <- secure(f)
} yield s
// kleisli composition attempt - alternative to filterAndSecure
val fk = kleisli[FreeString, String, String](filter _)
val sk = kleisli[FreeString, String, String](secure _)
val fAndS = fk >=> sk // this is where we have a compilation issue
}
For some reason what i get is this compilation error:
could not find implicit value for parameter b: scalaz.Bind[FreeString]
[error] val fAndS = sk >=> fk
feels like the implicit should be resolved since FreeC in a monad instance that implements a Bind trait and i am importing all of the Free implicit instances via import Free._
what am I missing here?
Thank you in advance!
Thank you Travis for your help. Bad type declaration was actually one of the culprits. With some help from the scalaz community via google groups and some tinkering here is the answer:
class BigBrother[F[_]](implicit I: Inject[Sensor,F]) extends AppCompose {
import BigBrother._
def log(log: String) = lift(Log(log))
def filter(log: String) = lift(Filter(log))
def secure(log: String) = lift(Secure(log))
def filterAndSecure(phrase: String) = for {
f <- filter(phrase)
s <- secure(f)
} yield s
type CoyoF[A] = Coyoneda[F, A]
type FreeCoF[A] = Free[CoyoF,A]
implicit val MonadFreeSensor = Free.freeMonad[FreeCoF]
// kleisli composition attempt - alternative to filterAndSecure
val fk = kleisli[FreeCoF, String, String](filter _)
val sk = kleisli[FreeCoF, String, String](secure _)
val fAndS = fk >=> sk
}
key is the correct type declaration and providing the type class monad instance for FreeCoF implicit val MonadFreeSensor = Free.freeMonad[FreeCoF]