我正在寻找一种简单的方法来编写函数
mapAndUnzip :: (Functor f) => (a -> (b,c)) -> f a -> (f b, f c)
我并不完全相信Functor
是一个足够强大的约束,但我会用它来具体化。我希望能够在f
具有类型(仅举几例)[]
,Data.Vector.Unboxed.Vector
以及[a]
和{{1}周围的自己的包装类型时应用此功能}}。 (其他可能的类型包括Vector a
,Repa矢量等。)
我的关键要求是不需要Array
这样的约束,只需要(Unbox (b,c))
。子要求:为每个输入元素仅计算一次函数。
我通过构建两个可变向量来为(Unbox b,Unbox c)
找到一种方法,因为我在输入上进行映射,但我希望有一种比为不同类型创建一个新类和我自己的实例更好的方法。 GHC.Util定义Vector
的特定于列表的方式让我觉得一个通用的解决方案可能是不可能的,但我认为在破解我自己的解决方案之前我会得到第二个意见。
答案 0 :(得分:1)
Functor
就够了,你可以这样做:
(编辑:只计算一次)
mapAndUnzip g fa = (fmap fst fbc, fmap snd fbc)
where
fbc = fmap g fa