cats Bifunctor[F[_, _]].bimap 函数中为什么有两个参数组?
Why are there two parameter groups in cats Bifunctor[F[_, _]].bimap function?
我在尝试为地图 (Bifunctor[Map[_, _]]
) 实现双函数类型 class 时偶然发现了这个问题。
Bifunctor 在猫中是这样定义的:
/**
* The quintessential method of the Bifunctor trait, it applies a
* function to each "side" of the bifunctor.
*
* Example:
* {{{
* scala> import cats.implicits._
*
* scala> val x: (List[String], Int) = (List("foo", "bar"), 3)
* scala> x.bimap(_.headOption, _.toLong + 1)
* res0: (Option[String], Long) = (Some(foo),4)
* }}}
*/
def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): F[C, D]
如评论所述,可以使用两个函数(在一个参数组中)作为其输入来调用此函数,如下所示:x.bimap(_.headOption, _.toLong + 1)
。这告诉我这显然不是被调用的 bimap
函数,因为它有两个参数组 ((fab: F[A, B])(f: A => C, g: B => D)
)。我一直想知道是否存在某种我不知道这里发生的隐式类型转换。它是如何工作的?我需要实现什么才能获得地图的 Bifunctor 类型 class?
class Bifunctor
类型的实例 Map
可以定义如下
implicit val mapBifunctor: Bifunctor[Map] = new Bifunctor[Map] {
override def bimap[A, B, C, D](fab: Map[A, B])(f: A => C, g: B => D): Map[C, D] =
fab.map { case (k, v) => f(k) -> g(v) }
}
在 x.bimap(_.headOption, _.toLong + 1)
中隐式解析了两次:
首先,实例Bifunctor[Tuple2]
被发现(import cats.instances.tuple._
或import cats.instances.all._
或import cats.implicits._
),
其次,扩展方法解析(import cats.syntax.bifunctor._
or import cats.syntax.all._
or import cats.implicits._
)
因此x.bimap(_.headOption, _.toLong + 1)
转化为
implicitly[Bifunctor[Tuple2]].bimap(x)(_.headOption, _.toLong + 1)
或
Bifunctor[Tuple2].bimap(x)(_.headOption, _.toLong + 1)
或
toBifunctorOps(x)(catsStdBitraverseForTuple2).bimap(_.headOption, _.toLong + 1)
我在尝试为地图 (Bifunctor[Map[_, _]]
) 实现双函数类型 class 时偶然发现了这个问题。
Bifunctor 在猫中是这样定义的:
/**
* The quintessential method of the Bifunctor trait, it applies a
* function to each "side" of the bifunctor.
*
* Example:
* {{{
* scala> import cats.implicits._
*
* scala> val x: (List[String], Int) = (List("foo", "bar"), 3)
* scala> x.bimap(_.headOption, _.toLong + 1)
* res0: (Option[String], Long) = (Some(foo),4)
* }}}
*/
def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): F[C, D]
如评论所述,可以使用两个函数(在一个参数组中)作为其输入来调用此函数,如下所示:x.bimap(_.headOption, _.toLong + 1)
。这告诉我这显然不是被调用的 bimap
函数,因为它有两个参数组 ((fab: F[A, B])(f: A => C, g: B => D)
)。我一直想知道是否存在某种我不知道这里发生的隐式类型转换。它是如何工作的?我需要实现什么才能获得地图的 Bifunctor 类型 class?
class Bifunctor
类型的实例 Map
可以定义如下
implicit val mapBifunctor: Bifunctor[Map] = new Bifunctor[Map] {
override def bimap[A, B, C, D](fab: Map[A, B])(f: A => C, g: B => D): Map[C, D] =
fab.map { case (k, v) => f(k) -> g(v) }
}
在 x.bimap(_.headOption, _.toLong + 1)
中隐式解析了两次:
首先,实例
Bifunctor[Tuple2]
被发现(import cats.instances.tuple._
或import cats.instances.all._
或import cats.implicits._
),其次,扩展方法解析(
import cats.syntax.bifunctor._
orimport cats.syntax.all._
orimport cats.implicits._
)
因此x.bimap(_.headOption, _.toLong + 1)
转化为
implicitly[Bifunctor[Tuple2]].bimap(x)(_.headOption, _.toLong + 1)
或
Bifunctor[Tuple2].bimap(x)(_.headOption, _.toLong + 1)
或
toBifunctorOps(x)(catsStdBitraverseForTuple2).bimap(_.headOption, _.toLong + 1)