我不明白为什么这段代码会编译:
def lift[A,B](f: A => B): Option[A] => Option[B] = _ map f
如果我这样做:
val f: Int => Double = _.toDouble
然后lift(f)
工作正常,但f map f
会出错:error: value map is not a member of Int => Double
答案 0 :(得分:2)
我不明白为什么这段代码会编译:
def lift[A,B](f: A => B): Option[A] => Option[B] = _ map f
这是
的缩写def lift[A,B](f: A => B): Option[A] => Option[B] = (o: Option[A]) => o map f
方法lift
返回一个函数:
- 需要Option[A]
- 使用某个函数f: A => B
修改该选项的内容
- 返回结果Option[B]
因此,当您“解除”某些功能f: A => B
时,您基本上将其从A => B
升级为Option[A] => Option[B]
。当这个新升级的功能被赋予o: Option[A]
时,它会将该选项的内容映射到Option[B]
(通过使用原始功能升级时提供的f: A => B
)。
如果我这样做:
val f: Int => Double = _.toDouble
然后提升(f)工作正常,但f map f给出错误
error: value map is > not a member of Int => Double
是的,因为您无法映射功能。你只能使用函数来映射某些东西(顺便说一句,你可以映射的东西叫做仿函数)。
您想要做的是:
val f: Int => Double = _.toDouble
)Int => Double
到Option[Int] => Option[Double]
Option[Int]
,从而将其转换为Option[Double]
。所以:
val f: Int => Double = _.toDouble
val upgraded = lift(f)
println(upgraded(Some(8))) // prints Some(8.0)
答案 1 :(得分:1)
lift
函数只是将函数f: A=> B
提升到某个其他域上的函数,在这种情况下它是Option[_]
。因此,lift
的实施为您提供了一个函数f&#39 ;:选项[A] =>选项[B],因为选项具有map
功能,您可以在第一个输入参数(这是'下划线')上调用它。
您不必致电f map f
。你做的是解除你的f函数:
val f: Int => Double = _.toDouble
val lifted = lift(f)
lifted(Some(42)) //it should be Some(42.0)