2013-12-20 39 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) 

似乎不可思议,我做这个简单的类型转换。可能意味着我忽略了一些东西。