11

私はこれをかなり使用します:

a' = [ (f x, f y) | (x, y) <- a ]

それを行うためのより良い方法はありますか?

4

3 に答える 3

14

(***)からの演算子を使用できますControl.Arrow

> map (f *** f) a

または独自のヘルパー関数を定義します

> let both f (x, y) = (f x, f y)
> map (both f) a
于 2012-10-23T02:38:07.820 に答える
11

代替ソリューション:

import Data.Bifunctor

bimap f f pair

Bifunctor.bimap基本的にはと同じですArrow.(***)が、他のバイファンクター(などEither a b)でも機能します。

余談:

あなたのケースに事前定義されたものがない理由は、同じ要素タイプを持つためにFunctorApplicativeなどのインスタンスを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)

同じ要素タイプのペアで多くの作業を行う場合は、(,)そのようなタイプに切り替えると便利です。

于 2012-10-23T06:30:52.820 に答える
5

を使用する場合は、、またはlensを使用できます。これには、より構成しやすいという利点があります。たとえば、リストのペアがある場合は、()のようなものを使用できます。over both fboth %~ fboth.mapped +~ toUpper:: ([Char],[Char]) -> ([Char],[Char])

于 2012-10-23T06:21:48.383 に答える