Scalaz 7 如何将 Functor 与 Function1 一起使用

Scalaz 7 how to use Functor with Function1

嗨,我开始学习 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}

我收到错误

Error:(10, 17) Function1 takes two type parameters, expected: one Functor[Function1].map{x:Int => x * 4}{(x:Int) =>x * 7}

我确实从文档中的一个有效示例中得到启发

Functor[Option].map(Some("adsf"))(_.length)

展开((x: Int) => x * 4) map ((x: Int) => x * 7)的隐式我们得到

ToFunctorOps(((x: Int) => x * 4))(function1Covariant) map ((x: Int) => x * 7)

function1Covariant 的签名是

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 require implicit

Functor[Int => ?]

function1Covariant[Int]: Monad[Int => ?] 满足,因为 MonadFunctor 的一种类型。因此我们可以明确地写

Functor[({type F[B] = Int => B})#F].map((x: Int) => x * 4)((x: Int) => x * 7)

或使用 kind-projector as

Functor[Int => ?].map((x: Int) => x * 4)((x: Int) => x * 7)

我接受了上面的答案,因为它解决了问题。它显示了如何做我想做的事。明确地使一个函数成为一个函子以便映射到它上面。但是我有点不满意为什么我必须这样做 ({type F[B] = Int => B})#F 来实现功能?为什么它不能完全通用,为什么图书馆不提供开箱即用的功能,而不是让用户这样做。

我相信我在以下帖子中找到了答案:

What are type lambdas in Scala and what are their benefits?

Why type lambdas?

基于此,我得出结论,当您没有 F[X](例如 F[Int, INT] 或 Map[Int, INT])时,库无法为您烘焙。需要手动求助于 Type lambda,这会迫使你做一些部分的事情。因此,我们不能在 FunctionX 的库中烘焙一些通用的东西。