任何人都可以帮助我从书中获得以下代码位吗?
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] =
?
感谢您的详细信息。
答案 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”部分。
希望现在更清楚了!