私はこれをかなり使用します:
a' = [ (f x, f y) | (x, y) <- a ]
それを行うためのより良い方法はありますか?
(***)からの演算子を使用できますControl.Arrow
> map (f *** f) a
または独自のヘルパー関数を定義します
> let both f (x, y) = (f x, f y)
> map (both f) a
代替ソリューション:
import Data.Bifunctor
bimap f f pair
Bifunctor.bimap基本的にはと同じですArrow.(***)が、他のバイファンクター(などEither a b)でも機能します。
余談:
あなたのケースに事前定義されたものがない理由は、同じ要素タイプを持つためにFunctor、Applicativeなどのインスタンスを2回書き込むことができないためです。(,)独自の「ベクトルのような」タイプを使用すると、この問題は発生しません。
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)
同じ要素タイプのペアで多くの作業を行う場合は、(,)そのようなタイプに切り替えると便利です。
を使用する場合は、、またはlensを使用できます。これには、より構成しやすいという利点があります。たとえば、リストのペアがある場合は、()のようなものを使用できます。over both fboth %~ fboth.mapped +~ toUpper:: ([Char],[Char]) -> ([Char],[Char])