从“Scala in Action”中输入投影示例(第8章)

时间:2013-08-11 16:14:11

标签: scala types

任何人都可以帮助我从书中获得以下代码位吗?

trait Mapper[F[_]] {
  def fmap[A, B](xs: F[A], f: A => B): F[B]   
}

def VectorMapper = new Mapper[Vector] {
  def fmap[A, B](xs: Vector[A], f: A => B): Vector[B] = xs map f 
}

这很简单:使用高级类型F[_]的特征定义用于任何"类似容器的"类型,然后是Vector的具体映射器。

然后是一个棘手的部分。 Either的映射器。 我理解{type E[A] = Either[X, A]}只是作为一个代码块,({type E[A] = Either[X, A]})#E作为一个投影,从匿名代码块中取出该类型别名E,并由该作者"隐藏&# 34; X特征的Mapper的存在,因为特征操作单一类型参数"容器类型"仅 - 我们对A感兴趣,即Right

def EitherMapper[X] = new Mapper[({type E[A] = Either[X, A]})#E ] {
    def fmap[A, B](r: Either[X, A], f: A => B): Either[X, B] = r match {
        case Left(a) => Left(a)
        case Right(a) => Right(f(a))
    }     
}

问题: 为什么X部分需要def EitherMapper[X] =

感谢您的详细信息。

1 个答案:

答案 0 :(得分:4)

要么取决于两种类型,例如Either[Int, String]

EitherMapper是一种仅依赖于一种类型的类型构造函数,因此当您拥有EitherMapper[Int]时,您正在处理Either[Int, A]A已解决进入Mapper部分,这样您就可以拥有任何A=>B函数,因为第一种类型的Either已经存在于Mapper中,并且您返回Either[X, B]

确实E [A]类型相当于[X,A],你对类型只有一个自由度!

val right: Either[Boolean, String] = Right("test")
val left: Either[Boolean, String] = Left(false)

println(EitherMapper.fmap(right, (s: String) => s.length))
> Right(4)
println(EitherMapper.fmap(left, (s: String) => s.length))
> Left(false)

在这种情况下,类型为EitherMapper[Boolean],fmap的类型为fmap[String, Integer],它接受​​Either[Boolean, String]并返回Either[Boolean, Integer]

正如您所看到的那样,fmap的类型在X类型的Either[X, A]部分没有说明任何内容,因此最后您可以将(s: String) => s.length)函数用于其他EitherMapper[X]函数{{1}} 1}}类型,简单来说,任何一种类型的“左”部分都可以是你想要的任何东西,它是类型构造的“X”部分。

希望现在更清楚了!