Haskell function from (a -> [b]) -> [a -> b]

You can generalize seperateFuncs to Applicative (or Monad) pretty cleanly:

seperateFuncs :: (Applicative f) => f (a -> b) -> (a -> f b)
seperateFuncs f x = f <*> pure x

Written in point-free style, you have seperateFuncs = ((. pure) . (<*>)), so you basically want unap . (. extract), giving the following definition if you write it in pointful style:

joinFuncs :: (Unapplicative f) => (a -> f b) -> f (a -> b)
joinFuncs f = unap f (\ g -> f (extract g))

Here I define Unapplictaive as:

class Functor f => Unapplicactive f where
    extract  :: f a -> a
    unap     :: (f a -> f b) -> f (a -> b)

To get the definitions given by leftaroundabout, you could give the following instances:

instance Unapplicative [] where
    extract = head
    unap f = [\a -> f [a] !! i | i <- [0..]]

instance Unapplicative ((->) c) where
    extract f = f undefined
    unap f = \x y -> f (const y) x

I think it's hard to come up with a "useful" function f :: (f a -> f b) -> f (a -> b) for any f that isn't like (->).


First of all, you can brute-force yourself this function all right:

joinFuncs f = [\x -> f x !! i | i<-[0..]]

but this is obviously troublesome – the resulting list is always infinite but evaluating the ith element with x only succeds if length(f x) > i.

To give a "real" solution to

The question then is there some datatype f which has a function :: (a -> f b) -> f (a -> b)?

Consider (->)c. With that, your signature reads (a -> (c->b)) -> (c->(a->b)) or equivalently (a -> c -> b) -> c -> a -> b which, it turns out, is just flip.

Of course, this is a bit of a trivial one since seperateFuncs has the same signature for this type...


"Is there some datatype f which has a function :: (a -> f b) -> f (a -> b)?"

In fact, there is an even more general version of this function in the Traversable type class, which deals with commutable functors:

class (Functor t, Foldable t) => Traversable t where

  ... 

  sequenceA :: Applicative f => t (f b) -> f (t b)

How is this related to your function? Starting from your type, with one type substitution, we recover sequenceA:

  1. (a -> f b) -> f (a -> b) ==> let t = (->) a
  2. t (f b) -> f (t b)

However, this type has the constraint that t must be a Traversable -- and there isn't a Traversable instance for (->) a, which means that this operation can't be done in general with functions. Although note that the "other direction" -- f (a -> b) -> (a -> f b) works fine for all functions and all Applicatives f.