2013-12-20 42 views
0

在我的代碼中的標準構造是一個函數,返回一個Reader [X,\/[A,B]],我想用於理解的任一部分,所以我一直試圖編寫一個將函數(X)=> \/[A,B]轉換爲EitherT [Reader [X,\/[A,B]],A,B]的函數。EitherT與閱讀器概括閱讀器輸入

我可以與X的預定類型比如做到這一點:

case class Config(host: String) 

    type ReaderConfig[C] = Reader[Config, C] 

    type EitherReaderConfig[A,B] = EitherT[ReaderConfig, A,B] 

    def eitherReaderF[A,B](f: Config => \/[A,B]) : EitherReaderConfig[A,B] = EitherT[ReaderConfig, A,B](Reader[Config, \/[A,B]](f)) 

    eitherReaderF(c => \/-(c.host)).run(Config("hostname")) 

不過,我有去除這個配置型和推廣了十問題,這是因爲EitherT的第一個參數是期待一個參數在它的類型構造:F [_]中,但是Reader被定義爲包含2:Reader [A,B]

我的一個嘗試是使用類型lambdas來定義類型。

type EitherReaderM[X,A,B] = EitherT[({type λ[α] = Reader[X, α]})#λ, A,B] 

    def eitherReaderM[X,A,B](f: X => \/[A,B]): EitherReaderM[X,A,B] = EitherT[({type λ[α] = Reader[X, α]})#λ, A,B](Reader(f)) 

    val r: EitherReaderM[Config, Int, String] = eitherReaderM((c: Config) => \/-(c.host)) 

    val run = r.run /// type returns scalaz.Kleisli[[+X]X,Config,scalaz.\/[Int,String]] 

    run.apply(Config("host")) // fails: value apply is not a member of scalaz.Kleisli[[+X]X,Config,scalaz.\/[Int,String]] 

最後一位失敗。我感覺就像我在這裏......

我不完全確定發生了什麼,但我可以用2個電話運行這個運行。一個在EitherT上,另一個在Kleisli上(我不確定它來自哪裏)。

run.run(Config("host")) 

但是,即使它在控制檯中運行,它實際上也不會編譯。編譯時收到此錯誤:

種類參數([α] scalaz.Kleisli [[+ X] X,X,α],A,B) 不符合預期種類的類型參數(類型F,類型A,類型B)。 [α] scalaz.Kleisli [[+ X] X,X,α]的類型參數不匹配F型的預期參數: 型α是不變的,但類型_聲明協

[錯誤]高清或者ReaderM [X,A,B](f:X =>/[A,B]):EitherReaderM [X,A,B] = EitherT({typeλ[α] = Reader [X,α]})#λ ,A,B

回答

0

在這裏,我們有它,最終的編譯版本。我覺得它可以簡化一點,但那是一個不同的日子。

type EitherReader[X,A,B] = EitherT[({type λ[+α] = Reader[X, α]})#λ, A,B] 

    def eitherReader[X,A,B](f: X => \/[A,B]): EitherReader[X,A,B] = EitherT[({type λ[+α] = Reader[X, α]})#λ, A,B](Reader(f)) 

允許我將Reader [X,A/B] .apply替換爲任一讀寫器[X,A,B]。

老:

def getSub(id: Int) = Reader[Config, String \/ Sub](config => config.findSub(id).right) 

新:

def getSub(id: Int) = eitherReader[Config, String, Sub]](config => config.findSub(id).right) 

似乎不可思議,我做這個簡單的類型轉換。可能意味着我忽略了一些東西。