2012-10-23 17 views

cevap

14

Sen lens kullanırsanız, over both f veya both %~ f kullanabilirsiniz Control.Arrow

> map (f *** f) a 

den (***) operatörü kullanabilir veya kendi yardımcı işlevi

> let both f (x, y) = (f x, f y) 
> map (both f) a 
+3

veya belki de sadece bir lambda: 'harita (\ (x, y) -> (f x, f y)) a' – MtnViewMark

5

tanımlayabilirsiniz. Bu, daha da karmaşık olmanın avantajına sahiptir - örneğin, bir çift listeniz varsa, both.mapped +~ toUpper (:: ([Char],[Char]) -> ([Char],[Char])) gibi bir şeyi kullanabilirsiniz.

11

Alternatif çözüm:

import Data.Bifunctor 

bimap f f pair 

Bifunctor.bimap de temelde Arrow.(***) aynıdır, ancak diğer bifunctors (gibi Either a b) için çalışır.

ARASÖZ:

orada durum için önceden tanımlanmış bir şey değildir aynı öğe iki kez yazın sahip (,) için Functor, Applicative vb örneklerini yazamazsınız olmasıdır sebebi.

data Pair a = Pair a a deriving Show 

instance Functor Pair where 
    fmap f (Pair x y) = Pair (f x) (f y) 

Şimdi map (fmap (+1)) [Pair 12 14, Pair 17 18] gibi şeyler yazabilirsiniz: Bir kendi "Vektör benzeri" tipi ile bu problemi olmazdı. Aynı-eleman tipi çiftleri ile çok çalışıyorsanız

instance Applicative Pair where 
    pure x = Pair x x 
    (Pair f g) <*> (Pair x y) = Pair (f x) (g y) 

, böyle bir karşı (,) geçiş yararlı olabilir: Eğer senin Pair üzerinde farklı işlemler kullanmak isterseniz Veya, bir adım daha ileri gidebilir yazın.

+0

Diggresyon için teşekkürler. –

İlgili konular