变换M [A => B]到A => M [B]

时间:2013-12-18 01:21:26

标签: scala functional-programming scalaz

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

def transform[M[_], A, B](m: M[A => B]): A => M[B] = ???

以下是List容器的示例实现:

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

理想情况下,这适用于任何函数容器,包括函数元组,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))

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

2 个答案:

答案 0 :(得分:5)

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

def mapply[A, B](a: A)(f: F[A => B]): F[B] = map(f)((ff: A => B) => ff(a))

所以你可以用它来写变换:

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

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

def transform[M[_]:Functor,A,B](m: M[A => B]):A => M[B] = _.mapply(m)

答案 1 :(得分:0)

我搜索了Scalaz源代码,它看起来像Functor一样:

def transform[M[_]: Functor, A, B](fs: M[A => B]): A => M[B] = a => fs map (_(a))