2012-10-06 16 views
13

Jestem nowy w Haskell, i zastanawiam się, czy istnieje lepszy sposób, aby dowiedzieć się, czy powiela się funkcjonalność biblioteki niż Hoogle?Monad m => a -> [a -> m a] -> m a

Sprawa w punkcie: Mam szereg funkcji f :: Monad a => a -> m a że chcą łańcucha razem, jak

f1234 x = (return x) >>= f1 >>= f2 >>= f3 >>= f4 

Ale wolałbym napisać

chain :: Monad m => a -> [a -> m a] -> m a 
chain = foldl (>>=) <$> return 
f1234 = (flip chain) [f1, f2, f3, f4] 

Wydaje się bardzo proste, robi podstawowa biblioteka oferuje coś podobnego do chain?

+1

Alternatywą dla hoogle jest, z odrobiną intuicji, zgadywanie najbardziej odpowiedniego modułu, a następnie przeglądanie jego strony z dokumentacją. Możesz znaleźć inny sposób skrócenia kodu lub znaleźć inną bardzo użyteczną funkcję, którą chcesz zapamiętać. Ta taktyka działa najlepiej z pakietem podstawowym, a następnie z modułami "abstrakcji" (jak Monad i Applictive, później bardziej zaawansowanym składanym i Traversalable) i sparametryzowanymi typowymi typami danych (np. Może, Lista). Chociaż można to zrobić również dla bardziej używanych typów danych (Dla mnie Map/Set, a później Monad Transformers). – Laar

+0

'łańcuch = foldl (>> =). return' jest *** o tyle jaśniejsze ***, IMHO. –

Odpowiedz

17

Hoogle jest do tego dobry i zdecydowanie jest odpowiednim narzędziem do znalezienia funkcji tego samego typu.

Ponieważ jest to proste i nie pojawia się w żadnym ze zwykłych miejsc, możesz napisać to samo jako import z jakiegoś niejasnego modułu, częściowo dlatego, że nie importujesz całego ładunku innych rzeczy.

(Na marginesie: Niektóre pakiety nie wydają się być przeszukiwać od hoogle, więc jeśli znasz nazwy funkcji, moduł lub pakiet jesteś po i hoogle nie wie, stosowanie hayoo.)

Chciałbym podłączyć

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c) 

z Control.Monad. To operator kompozycji, który zawsze chciałem, dopóki go nie znalazłem. Jest to bardziej naturalny sposób pracy z monadami niż moim zdaniem: >>=.

Można nawet użyć go bezpośrednio, to jest tak oczywiste:

f1234 = f1 >=> f2 >=> f3 >=> f4 

To pokazuje się jeśli hoogle dla (a -> m a) -> (a -> m a) -> (a -> m a), więc przyszła strategia jeśli szukasz czegoś, co łączy się lista coś jest wyszukaj funkcję, która łączy dwa i użyj jednej z funkcji fold.

Zatem

chain' :: Monad m => [a -> m a] -> a -> m a 
chain' = foldr (>=>) return 

f1234 = chain' [f1,f2,f3,f4] 

lub

chain'' :: Monad m => a -> [a -> m a] -> m a 
chain'' = flip $ foldr (>=>) return 

jeśli wolisz, ale twój jest w porządku i tak.

+5

Zauważ, że 'f1> => f2> => f3> => f4' jest bardziej ogólne niż' łańcuch '[f1, f2, f3, f4] 'ponieważ pozwala komponować' a -> mb' i 'b - > mc'. – nponeccop

Powiązane problemy