MapAndUnzip generalization

I am looking for an easy way to write a function

mapAndUnzip :: (Functor f) => (a -> (b,c)) -> f a -> (f b, f c)

I'm not quite sure what Functoris a strong enough restriction, but I will use it for specificity. I want to use this function when it fhas a type (to indicate several) [], Data.Vector.Unboxed.Vectorand my own types of wrappers around [a]and Vector a. (Other possible types include Array, Repa vectors, etc.)

My key requirement is that I do not need a restriction, for example (Unbox (b,c)), only (Unbox b,Unbox c). Subrequirement: calculate a function only once for each input element.

I see a way to do this for Vectorby building two mutable vectors when I overlay on the input, but I hope there will be a better way than creating a new class and own instances for different types. The list-specific way that GHC.Util defines mapAndUnzipit makes me think that a general solution may not be possible, but I decided that I would get a second opinion before hacking my own solution.

+4
source share
1 answer

Functor enough you can do:

(EDIT: calculate g only once)

mapAndUnzip g fa = (fmap fst fbc, fmap snd fbc)
  where
    fbc = fmap g fa
+1
source

All Articles