2015-09-09 73 views
2

預先感謝您的幫助無法通過Coyoneda找到免費單子綁定實例

我有2個功能,我想通過Kleisli箭頭組成。這些函數接受String併產生FreeC。 kleisli箭頭創建時沒有問題,但編譯器抱怨找不到。我會切出部分代碼進行簡單:

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 

} 

出於某種原因,我所得到的是這樣的編譯錯誤:

could not find implicit value for parameter b: scalaz.Bind[FreeString] 
[error] val fAndS = sk >=> fk 

感覺就像隱應該因爲FreeC在一個單子實例中解決了實現綁定特質,我通過導入自由導入所有免費隱式實例._

我在這裏丟失了什麼?

預先感謝您!

+0

你能提供一個可行的例子嗎? '類型FreeString [A] = FreeC [F,String]'不能編譯。 –

+0

我假設你的意思是'類型FreeString [A] = FreeC [Sensor,A]'? –

+0

@TravisBrown感謝您的回覆。不,我的原始類型聲明仍然存在,它編譯 - 但我沒有給代碼足夠的上下文。我更新了代碼片段以包含更多上下文。如果不是試圖做kleisli組合的代碼編譯很好。請注意:這裏的大圖是基於Free Monad的dsl--爲簡潔起見,我不包含其他代數。如果這沒有任何意義,我可以把完整的代碼寫成一個要點 - 讓我知道。再次感謝你! – vadimich

回答

1

謝謝特拉維斯的幫助。壞類型聲明實際上是罪魁禍首之一。從通過谷歌組scalaz社區一些幫助和一些修修補補這裏就是答案:

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 

} 

關鍵是正確類型聲明和FreeCoF 提供類型的類實例單子隱VAL MonadFreeSensor = Free.freeMonad [FreeCoF ]