2009-02-23 18 views
60

Co to jest Fusion Stream Haskella i jak z niego korzystać?Co to jest Haskell Stream Fusion

+1

Czy jest coś, co musisz wiedzieć, o czym nie jest już mowa w [tym wpisie] (http://www.randomhacks.net/articles/2007/02/10/map-fusion-and-haskell-performance " Map fusion: Ulepszenie Haskella o 225% ")? Jeśli tak, to czy możesz być bardziej konkretny? –

+0

Powiązane: http://lambda.jstolarek.com/2013/04/haskell-as-fast-as-ca-case-study/ –

+1

Uwaga: istnieje również coś o nazwie List Fusion, które dzieje się automatycznie z wieloma wbudowanymi w funkcjach: https://downloads.haskell.org/~ghc/7.4.2/docs/html/users_guide/rewrite-rules.html#id690070 i zobacz http: // conscientiousprogrammer.com/blog/2015/12/19/24-dni-of-hackage-2015-day-19-ghc-core-html-list-fusion-sprawdzanie-sondowania-ghcs-fusion-przepisywanie-reguł-do-kasowania- intermediate-data-from-exist/jak sprawdzić, czy jest używany (lub spróbuj 'stack build --ghc-options '-ddump-rule-firings -ddump-rule-rewrites" && find .stack-work/-name "* dump-rule *"). – unhammer

Odpowiedz

60

Papier, na który wskazuje Logan, jest świetny, ale jest trochę trudny. (Po prostu zapytajcie moich uczniów.) Jest to także świetny temat "jak działa fuzja strumieniowa" i tylko ułamek "jaka jest fuzja strumieniowa i jak można z niej korzystać".

Problem, że strumień Fusion rozwiązuje to, że kody funkcyjne jak napisane często przeznaczyć list pośrednie, na przykład, aby utworzyć nieskończoną listę numerów węzłów, można napisać

nodenames = map ("n"++) $ map show [1..] 

kod Naiwne byłoby przeznaczyć nieskończoną listę liczby całkowite [1, 2, 3, ...], nieskończona lista ciągów znaków ["1", "2", "3", ...], a ostatecznie nieskończona lista nazw ["n1", "n2", "n3", ...]. To zbyt dużo alokacji.

To, co robi fuzja strumieniowa, to przetłumaczenie definicji takiej jak nodenames na coś, co wykorzystuje funkcję rekursywną, która przydziela tylko to, co jest potrzebne do wyniku. Ogólnie rzecz biorąc, eliminacja alokacji list pośrednich nazywa się wylesieniem .

Aby korzystać fuzję Stream, trzeba napisać nierekursywnych lista funkcji które używają funkcji z biblioteki strumień fuzyjnego opisanego w GHC ticket 915 (map, foldr, i tak dalej) zamiast wyraźnej rekursji. Ta biblioteka zawiera nowe wersje wszystkich funkcji Prelude, które zostały przepisane w celu wykorzystania fuzji strumieniowej. Wygląda na to, że ten materiał ma zostać wprowadzony do następnego wydania GHC (6.12), ale nie jest w obecnej stabilnej wersji (6.10). Jeśli chcesz korzystać z biblioteki Porges ma ładne proste wyjaśnienie w swojej odpowiedzi.

Jeśli naprawdę chcesz wyjaśnić, w jaki sposób działa fuzja strumieniowa, opublikuj kolejne pytanie - ale to znacznie trudniejsze.

+6

Czy są jakieś plany, aby uczynić to domyślnym zachowaniem listy preludiów? –

+1

Czy istnieje różnica w fuzji między aplikacją '$' i skład '.? – CMCDragonkai

+1

Czy funkcje Prelude są w jakiś sposób oznaczone, czy co? To znaczy. dlaczego nie będzie działać dla własnej funkcji rekursywnej? –

12

O ile mi wiadomo, i wbrew temu, co powiedział Norman, Fusion strumień nie obecnie wdrażane w bazie GHC (tj. Nie można po prostu użyć funkcji Prelude). Aby uzyskać więcej informacji, zobacz GHC ticket 915.

Aby użyć fuzji strumieniowej, należy zainstalować bibliotekę strumieniowo-fusion, zaimportować Data.List.Stream (można również zaimportować Control.Monad.Stream) i używać tylko funkcji z tego modułu, a nie funkcji Prelude. Oznacza to importowanie preludium, ukrywając wszystkie domyślne funkcje list, a nie używając [x..y] konstruktów lub rozumienia list.

-1

Czy to nie prawda, że ​​gdy GHC w wersji 6.12 używa domyślnie tych nowych funkcji, będą one również implementować [x ..y] i rozumieć listy w ten sposób nierekurencyjny? Ponieważ jedynym powodem, dla którego nie są one prawidłowe, jest to, że są one wewnętrzne i nie są naprawdę napisane w Haskell, ale bardziej jak słowa kluczowe, ze względu na szybkość i/lub dlatego, że nie będzie można na nowo zdefiniować tej składni.