ham*_*mar 14

您可以使用(***)运营商Control.Arrow

> map (f *** f) a
Run Code Online (Sandbox Code Playgroud)

或定义自己的帮助函数

> let both f (x, y) = (f x, f y)
> map (both f) a
Run Code Online (Sandbox Code Playgroud)

  • 或者只是一个lambda:`map(\(x,y) - >(fx,fy))a` (3认同)

Lan*_*dei 11

替代方案:

import Data.Bifunctor

bimap f f pair
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

现在你可以写出类似的东西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)
Run Code Online (Sandbox Code Playgroud)

如果您使用相同元素类型对进行大量工作,则切换到此类型可能很有用(,).


sha*_*haf 5

如果您使用lens,您可以使用over both f,或both %~ f.这具有更易组合的优点 - 例如,如果您有一对列表,则可以使用类似both.mapped +~ toUpper(:: ([Char],[Char]) -> ([Char],[Char]))的内容.