2013-05-21 23 views
15

Czasami chcesz złożyć listę krotek w jedną krotkę, używając różnych funkcji składania. Na przykład, aby skleić ze sobą listę wyników runState, uzyskując (w pewnym sensie) stan połączony i wynik łączony.Używanie strzałek w celu złożenia listy krotek

Rozważmy następujący realizacji:

wish :: (a -> a' -> a) -> (b -> b' -> b) -> (a,b) -> [(a', b')] -> (a,b) 
wish lfn rfn x xs = foldl (\(a,b) -> (lfn a) *** (rfn b)) x xs 

Chociaż to działa, czuję się niezręcznie o tym lambda. lfn *** rfn sam w sobie ma typ (a,b) -> (a -> a', b -> b'), którego nie mogę znaleźć sposobu, aby poprawnie zastosować do krotki bez konieczności odwoływania się do dopasowywania wzorca. Czy brakuje mi jasnego i eleganckiego sposobu? Może to być funkcja biblioteczna typu (a,a') -> (a -> a, a' -> a') -> (a, a') lub całkiem inne podejście.

+2

Pewna klasa BiAplikatywna zrobiłaby .. Prawdopodobnie jest gdzieś w hackage, ale zostawię to innym, aby opisać, które z nich są dobre i nie są przestarzałe. – Carl

+0

http://squing.blogspot.com/2008/11/beautiful-folding.html i jego pojawienie się w Hackage, http://hackage.haskell.org/package/ZipFold –

Odpowiedz

9

Control.Arrow nie zwraca uwagi na funkcje wyższego poziomu. To, czego naprawdę chcesz, to funkcja foo :: (a -> a' -> a'') -> (b -> b' -> b'') -> (a,b) -> (a',b') -> (a'',b''), analogia (***) dla funkcji arii 2. Istnieje taka funkcja w Data.Biapplicative (z pakietu bifunctor), która ma nieco bardziej ogólny podpis biliftA2 :: Biapplicative w => (a -> b -> c) -> (d -> e -> f) -> w a d -> w b e -> w c f. Ponieważ istnieje instancja Biaplikative dla dwuelementowych krotek, to wszystko, czego potrzebujesz.

Jedyny zarzut, jaki widzę przeciwko waszemu kodowi w jego obecnym stanie, to to, że currying of the lambda jest nieoczywisty; Mogę wolę bardziej jednoznaczne \(a,b) (a',b') -> (lfn a a', rfn b b').

Edytuj uwagi: Doszedłem do wniosku, że potrzebna funkcja nie istnieje i zasugerowałem jej zdefiniowanie; pobudzony komentarzem Carl, znalazłem ten w Biaplikicative (bardziej ogólny typ podpisu uniemożliwił Hoogle znalezienie go pod moim sugerowanym podpisem).

+0

Przechodzenie do ręcznej dekompozycji krotki z '\ (a , b) (a ', b') -> ... trochę sprzeciwia się celowi użycia jakiejś wymyślnej koncepcji, aby napisać wszechpotężny jednolinijkowy. Dziękuję za skierowanie do Biaplikicative, zagłębię się w to. –

+0

Chodzi mi o to, że chociaż 'Biapplicative' (<<**>>) 'ma typ, który musisz zastosować' (lfn *** rfn) ', wywołanie strzałek wydaje mi się tutaj nie na miejscu. Ale to tylko moja intuicja; podejście oparte na strzałach jest poprawne, jeśli niekoniecznie jasne. Ale wolę '(lfn \' biLiftA2 \ 'rfn)' do jawnej lambda. – isturdy

Powiązane problemy