Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transform an M[A => B] to an A => M[B]

Does there exist a utility in Scala or Scalaz to transform a container/collection of functions to a function that maps from the same input to a collection output values? The signature would look something like

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

Here's an example implementation for the List container:

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

Ideally, this would work for any function container, including a tuple of functions, an Option[Function1[A, B]], or even a TupleN[Option[Function1[A, B]], ...].

EDIT:

I've just realized that (at least for the special case of a List) the map function works:

    def transform[A, B](fs: List[A => B]): A => List[B] = x => fs map (_(x))

This can generalize to anything that has a map function with the appropriate semantics. What's the appropriate type class for this?

like image 654
Ben Sidhom Avatar asked Dec 18 '13 01:12

Ben Sidhom


1 Answers

Assuming M is a Functor, mapply in scalaz's Functor has a similar type signature:

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

So you could write transform in terms of that:

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

Edit: Another implementation using features from FunctorSyntax:

def transform[M[_]:Functor,A,B](m: M[A => B]):A => M[B] = _.mapply(m)
like image 160
Kristian Domagala Avatar answered Oct 10 '22 00:10

Kristian Domagala