嗨,我正在注视着学习Scalaz。
我想获取一个函数并与另一个函数映射。
尽管我能写这个:
import scalaz._, Scalaz._
import std.function._
import syntax.monad._
((x: Int) => x + 1) map {_ * 7}
它起作用,当我按照github项目中的示例使用显式方法时,它不起作用(见下文)
import scalaz._, Scalaz._
import std.option._
import std.function._
import syntax.monad._
Functor[Function1[Int,Int]].map{x:Int => x * 4}{(x:Int) =>x * 7}
我得到错误
错误:(10,17)Function1需要两个类型参数,一个: Functor [Function1] .map {x:Int => x * 4} {(x:Int)=> x * 7}
我确实从一个有效的文档示例中启发了自己
Functor[Option].map(Some("adsf"))(_.length)
答案 0 :(得分:2)
我们得到((x: Int) => x * 4) map ((x: Int) => x * 7)
的隐式扩展
ToFunctorOps(((x: Int) => x * 4))(function1Covariant) map ((x: Int) => x * 7)
implicit def function1Covariant[T]: Monad[T => ?] with ...
Functor.apply的第一个签名是
def apply[F[_]](implicit F: Functor[F]): Functor[F] = F
将F[_]
替换为({type F[B] = Int => B})#F
,或将kind-projector
替换为Int => ?
,我们使apply
要求隐式
Functor[Int => ?]
由于function1Covariant[Int]: Monad[Int => ?]
是Monad
的一种类型,因此Functor
满足的。这样我们就可以写清楚
Functor[({type F[B] = Int => B})#F].map((x: Int) => x * 4)((x: Int) => x * 7)
或使用kind-projector作为
Functor[Int => ?].map((x: Int) => x * 4)((x: Int) => x * 7)
答案 1 :(得分:0)
我接受了以上答案,因为它可以解决问题。它显示了如何做我想做的事。显式地将函数设为函子,以便在其上进行映射。但是,我对为什么必须为此功能({type F[B] = Int => B})#F
感到有些不满意?为什么它不能完全通用,为什么该库没有开箱即用,而不是让用户这样做。
我相信我已经在以下帖子中找到了答案:
What are type lambdas in Scala and what are their benefits?
基于此,我得出结论,只要您没有F [X](例如F [Int,INT]或Map [Int,INT]),该库就无法为您烘焙。需要手动求助于lambda类型,这会迫使您做部分操作。因此,对于FunctionX,我们无法在泛型库中添加一些通用的东西。