2011-10-06 29 views
15

Powiel możliwe:
Haskell: some and many
Haskell - What is Control.Applicative.Alternative good for?funkcje z 'Alternative' klasy typu

Jakie są funkcje some i many w klasie Alternative typu przydatna? Docs zapewniają definicję rekurencyjną, której nie mogłem zrozumieć.

+0

@Landei: Przeczytałem odpowiedź w tym wątku i nadal nie rozumiem. – missingfaktor

+0

Powiedziałem, że to pytanie jest duplikatem, nie że oryginał miał dobrą odpowiedź :-) Chociaż było wystarczająco dobre dla mnie: doszedłem do wniosku, że te funkcje prawdopodobnie nie są dla mnie interesujące ... – Landei

+0

@Landei: Osiągam ten sam wniosek co ty. :-) – missingfaktor

Odpowiedz

33

some i many można zdefiniować jako:

some f = (:) <$> f <*> many f 
many f = some f <|> pure [] 

Może to pomaga, aby zobaczyć jak some byłby napisany z monadycznej do składnię:

some f = do 
    x <- f 
    xs <- many f 
    return (x:xs) 

Więc some f biegnie f raz, potem „wielu "razy i zawiera wyniki. many f uruchamia f "niektóre" razy lub "alternatywnie" po prostu zwraca pustą listę. Chodzi o to, aby oboje uruchamiać f tak często, jak to możliwe, aż "zawiedzie", zbierając wyniki na liście. Różnica polega na tym, że some f nie powiedzie się, jeśli f natychmiast ulegnie awarii, a many f powiedzie się i "zwróci" pustą listę. Ale to, co to wszystko znaczy dokładnie, zależy od tego, jak zdefiniowano <|>.

Czy jest to przydatne tylko podczas analizowania? Zobaczmy, co robi dla instancji w bazie: Maybe, [] i STM.

Pierwsza Maybe. Nothing oznacza błąd, a więc some Nothing również się nie powiedzie i ulegnie zmianie na Nothing, a many Nothing zastąpi i oceni na Just []. Zarówno some (Just()), jak i many (Just()) nigdy nie wrócą, ponieważ Just() nigdy nie zawodzi! W pewnym sensie oceniają one na Just (repeat()).

Na listach [] oznacza awarię, więc some [] ocenia się [] (brak odpowiedzi), podczas gdy many [] ocenia się [[]] (istnieje jedna odpowiedź i jest pusta lista). Ponownie some [()] i many [()] nie wracają. Poszerzanie instancji, some [()] oznacza fmap (():) (many [()]) i many [()] oznacza oznacza some [()] ++ [[]], więc możesz powiedzieć, że many [()] jest taki sam jak tails (repeat()).

Dla STM, niepowodzenie oznacza, że ​​transakcję należy ponowić. Tak więc some retry spróbuje ponownie, podczas gdy many retry po prostu zwróci pustą listę. some f i many f będzie wielokrotnie uruchamiać f, aż się powtórzy. Nie jestem pewien, czy to jest przydatne, ale zgaduję, że nie jest.

Więc dla Maybe, [] i STMmany i some nie wydają się być tak użyteczne.Jest to użyteczne tylko wtedy, gdy aplikator ma jakiś stan, który sprawia, że ​​awarie stają się coraz bardziej prawdopodobne, gdy w kółko działa się to samo. W przypadku analizatorów składni jest to dane wejściowe, które maleją przy każdym pomyślnym dopasowaniu.

8

Np. dla parsing (patrz sekcja "Przykład zastosowania według przykładu").

+2

Nie znam parsetu. Byłbym wdzięczny za wyjaśnienia. – missingfaktor

+2

O ile rozumiem, jeśli masz parser 'p' dla X, to' some p' jest parserem dla 0 lub więcej X i 'wiele p' jest parserem dla 1 lub więcej X. – Ingo

+2

@missingfaktor' niektóre 'i' many' są implementowane pod względem '<|>'. Ten kombinator jest użyteczny również w inny sposób. Rozważ "Albo": "Tylko 0 <|> Tylko 1 = Tylko 0", "Nic" <|> Tylko 2 = Tylko 2 "," Tylko 3 <|> Nic = Tylko 3 "," Nic "<|> Nic = Nic" – fuz

Powiązane problemy