Mam pewne doświadczenie w pisaniu małych narzędzi w Haskell i uważam, że korzystanie z nich jest bardzo intuicyjne, szczególnie w przypadku pisania filtrów (używania interact
), które przetwarzają standardowe wejście i przesyłają je do standardowego wyjścia.
Ostatnio próbowałem użyć jednego takiego filtru w pliku, który był około 10 razy większy niż zwykle i dostałem Stack space overflow
błąd.
Po przeczytaniu (np. Tutaj i tutaj ) zidentyfikowałem dwie wskazówki, aby zaoszczędzić miejsce na stosie (doświadczeni Haskellerzy, poprawcie mnie, jeśli napiszę coś, co jest nieprawidłowe):
- Unikaj rekurencyjnych wywołań funkcji, które nie są rekurencyjne (dotyczy to wszystkich języków funkcjonalnych, które obsługują optymalizację wywołania ogona).
- Wprowadź,
seq
aby wymusić wczesną ocenę podwyrażeń, aby wyrażenia nie rosły zbyt duże, zanim zostaną zmniejszone (jest to specyficzne dla Haskell lub przynajmniej języków używających leniwej oceny).
Po wprowadzeniu pięciu lub sześciu seq
wywołań w moim kodzie moje narzędzie ponownie działa płynnie (także w przypadku większych danych). Uważam jednak, że oryginalny kod był nieco bardziej czytelny.
Ponieważ nie jestem doświadczonym programistą Haskell, chciałem zapytać, czy wprowadzenie seq
w ten sposób jest powszechną praktyką i jak często można to zobaczyć seq
w kodzie produkcyjnym Haskell. Czy są jakieś techniki, które pozwalają uniknąć seq
zbyt częstego używania i nadal zajmują mało miejsca na stosie?