将M [A => B]变换为A => M [B]

Ben*_*hom 5 functional-programming scala scalaz

Scala或Scalaz中是否存在将容器/函数集合转换为从同一输入映射到集合输出值的函数的实用程序?签名看起来像

def transform[M[_], A, B](m: M[A => B]): A => M[B] = ???
Run Code Online (Sandbox Code Playgroud)

这是List容器的示例实现:

def transform[A, B](fs: List[A => B]): A => List[B] = x =>
  fs.foldRight[List[B]](Nil) {
    (f, acc) => f(x) :: acc
  }
Run Code Online (Sandbox Code Playgroud)

理想情况下,这适用于任何函数容器,包括函数元组Option[Function1[A, B]],甚至是函数元组TupleN[Option[Function1[A, B]], ...].

编辑:

我刚刚意识到(至少对于List的特殊情况)map函数是有效的:

    def transform[A, B](fs: List[A => B]): A => List[B] = x => fs map (_(x))
Run Code Online (Sandbox Code Playgroud)

这可以推广到具有适当语义的map函数的任何东西.什么是适合的类型?

Kri*_*ala 6

假设M是一个Functor,mapply在scalaz中Functor有一个类似的类型签名:

def mapply[A, B](a: A)(f: F[A => B]): F[B] = map(f)((ff: A => B) => ff(a))
Run Code Online (Sandbox Code Playgroud)

所以你可以用这个来写变换:

def transform[M[_],A,B](m: M[A => B])(implicit f:Functor[M]):A => M[B] = f.mapply(_)(m)
Run Code Online (Sandbox Code Playgroud)

编辑:使用以下功能的另一个实现FunctorSyntax:

def transform[M[_]:Functor,A,B](m: M[A => B]):A => M[B] = _.mapply(m)
Run Code Online (Sandbox Code Playgroud)