我使用了这一点:
a' = [ (f x, f y) | (x, y) <- a ]
有更好的方法吗?
答案 0 :(得分:14)
您可以使用(***)
Control.Arrow
运算符
> map (f *** f) a
或定义自己的帮助函数
> let both f (x, y) = (f x, f y)
> map (both f) a
答案 1 :(得分:11)
替代解决方案:
import Data.Bifunctor
bimap f f pair
Bifunctor.bimap
与Arrow.(***)
基本相同,但也适用于其他bifunctors(如Either a b
)。
<强>题外话:强>
为您的案例预定义的原因是您无法为具有相同元素类型两次的Functor
编写Applicative
,(,)
等实例。使用自己的“矢量类”类型,你不会遇到这个问题:
data Pair a = Pair a a deriving Show
instance Functor Pair where
fmap f (Pair x y) = Pair (f x) (f y)
现在你可以写map (fmap (+1)) [Pair 12 14, Pair 17 18]
之类的东西了。或者,如果您想在Pair
上使用不同的操作,则可以更进一步:
instance Applicative Pair where
pure x = Pair x x
(Pair f g) <*> (Pair x y) = Pair (f x) (g y)
如果您使用相同元素类型对进行了大量工作,那么从(,)
切换到这样的类型可能会很有用。
答案 2 :(得分:5)
如果您使用lens
,则可以使用over both f
或both %~ f
。这具有更易组合的优势 - 例如,如果您有一对列表,则可以使用both.mapped +~ toUpper
(:: ([Char],[Char]) -> ([Char],[Char])
)之类的内容。