2011-07-22 23 views
17

W Haskell, Iteratee based I/O wydaje się bardzo atrakcyjny. Iteratees to składane, bezpieczne i szybkie sposoby na wykonywanie operacji wejścia/wyjścia inspirowane funkcją "fold" a.k.a. "reduce" w językach funkcjonalnych. Zasadniczo, jeśli masz ruch, chodzi o enkapsulację stanu przejścia do tak zwanego "modułu wyliczającego", który wywołuje "iteratee", który z kolei jest funkcją zwracającą wartość lub żądanie więcej danych wraz z kontynuacją aby moduł wyszukujący mógł zadzwonić. Tak więc tylko moduł wyliczający zna stan przejścia, a iteratee wie, co zrobić z danymi i buduje z nich wartości. Zaletą jest to, że iteraty są automatycznie kompozycyjne, gdzie wyjście jednego iteratee jest przekazywane do drugiego, aby zrobić większy.Czy iteratee I/O ma sens w niefunkcjonalnych językach?

Więc dwa pytania:

  • Czy pojęcie nawet zrobić sence w innych językach, jak zwykły językach obiektowych czy jest to przydatne tylko dla przezwyciężenia braków Haskell za leniwa I/O?
  • Czy są jakieś rzeczywiste implementacje dla innych języków, szczególnie C# (jak to jest to, czego używa moja firma)? (W wyszukiwarce Google pojawia się jedna wzmianka o iteratach w Scali, cóż, nie jestem teraz zainteresowany Scalą).
+0

Czy to w zasadzie nie jest przeznaczone dla nowych elementów asynchronicznych w C# 5.0? Mechanizm jest inny, ale podstawowa implementacja jest w zasadzie kontynuacją. –

+0

Dzięki za wskazanie tego - jeszcze nie wiedziałem o tym, i to na pewno wygląda ekscytująco, więc muszę się w to zagłębić, choć nie widzę zbyt wiele, by miało to coś wspólnego z iteratami. ;-) – firefrorefiddle

Odpowiedz

8
+0

Z tego, co widzę na pierwszy rzut oka, myślę, że masz rację! Dzięki, zagłębię się w nie. – firefrorefiddle

+0

Mam nie zakończoną implementację. Pokazuje podstawową strukturę. https://gist.github.com/4025522. Istnieje różnica, że ​​Obserwator nie może wysyłać wiadomości do obserwowalnego (tylko Wyrejestrowanie za pośrednictwem IDisposable), ale iteratee może wysyłać wiadomości do modułu wyliczającego. –

8

Przede wszystkim uświadomić sobie, że Haskell w „Lazy IO” to rodzaj hack, który rozkłada czystość w ograniczony sposób, aby umożliwić I/O, aby pojawić się na żądanie, jak dane są spożywane leniwie. Jest to normalne działanie w nieczystym języku, a leniwy ciąg może stworzyć ten sam problem w dowolnym miejscu. Więc jeśli robisz coś takiego, powiedzmy, pokazując interfejs IEnumerable do pliku i czytając go przyrostowo w miarę wyliczania sekwencji, to tak naprawdę nie jest inaczej.

Po drugie, iteraty i enumeratory mogą być również składane w tak zwane (w nieco niezdarnym stylu) enumeratees. W tym momencie masz coś, co jest zasilane danymi sekwencyjnymi, tworząc przyrostowe wyniki, gdy są gotowe, i dostarczając te wyniki do czegoś innego. Jest to w zasadzie wiele procesorów strumieniowych, których koncepcja prawdopodobnie znacznie wyprzedza zarówno Haskella, jak i C#.

Po trzecie, iteraty są enkapsulacją abstrakcyjnych zachowań, z ich wewnętrznymi działaniami ukrytymi. Jest to prawdopodobnie bardziej zgodne z zasadami OO niż z programowaniem funkcjonalnym w stylu ML, przynajmniej w sensie "zasad OO", które są popierane przez ludzi, którzy krzyczą na ciebie za używanie modułów pobierających i ustawiających i myślę, że przepływ kontroli powinien być realizowany za pośrednictwem wielopostaciowość.

Biorąc pod uwagę powyższe, powiedziałbym, że koncepcja iteratee pasowałaby dobrze w języku C# i byłaby najbardziej naturalnie zaimplementowana jako odwrócony odpowiednik IEnumerable, z obiektami przepływu danych kompozycyjnych i interfejsem "push" zamiast standardowego stylu "pull" LINQ.

+0

Dzięki za wspaniałe wyjaśnienie! – firefrorefiddle

+0

@Mike Hartl: I za to, co jest warte, zapomniałem o rozszerzeniach reaktywnych; po zerknięciu na link Charles podał to całkiem wyraźnie na tej samej zasadzie co to, co opisuję. –

Powiązane problemy