![](/img/trans.png)
[英]Getting StackOverFlowError on example from “Programming in Scala Third Edition” Chapter 10
[英]Type projection example from “Scala in Action” (chapter 8)
任何人都可以帮助我从书中下面的代码位?
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
的具体映射器。
然后是一个棘手的部分。 Mapper for Either
。 我理解{type E[A] = Either[X, A]}
只是作为一个代码块,并且({type E[A] = Either[X, A]})#E
作为采用该类型别名的投影E
出于匿名代码块而由该作者“隐藏” X
对Mapper
特征的存在,因为trait仅对单一类型参数“容器类型”进行操作 - 我们对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))
}
}
问题:为什么我们在def EitherMapper[X] =
part中需要X
?
谢谢你的详细信息
要么取决于两种类型,例如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的类型在Either[X, A]
类型的X
部分没有说什么,所以最后你可以使用(s: String) => s.length)
函数给别人EitherMapper[X]
类型,简单来说,任何一种类型的“左”部分都可以是你想要的任何东西,它是类型结构的“X”部分。
希望现在更清楚了!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.