Dlaczego seq jest zły?

Haskell ma magiczną funkcję o nazwie seq, która pobiera argument dowolnego typu i redukuje go do słaba Głowa normalna forma (WHNF).

Czytałem kilka źródeł [nie żebym pamiętał kim oni byli } teraz...], które twierdzą ,że "polimorficzny {[0] } jest zły". W jakim sensie są "źli"?

Podobnie istnieje funkcja rnf, która redukuje argument do postaci normalnej (NF). Ale ta {[12] } jest metodą klasową; nie działa dla dowolne typy. Wydaje mi się" oczywiste", że można zmienić specyfikację języka, aby zapewnić to jako wbudowany prymityw, podobny do seq. Prawdopodobnie byłoby to "jeszcze bardziej złe" niż tylko posiadanie seq. W jaki sposób to się dzieje?

[[10]}wreszcie ktoś zasugerował, że dając seq, rnf, par i podobny typ jak funkcja id, a nie Funkcja const Jak jest teraz, byłby ulepszeniem. Jak to?
Author: nominolo, 2012-10-02

2 answers

Z tego, co wiem, funkcja polimorficzna seq jest zła, ponieważ osłabia twierdzenia swobodne lub, innymi słowy, niektóre równania, które są ważne Bez seq, nie są już ważne z seq. Na przykład, równość

map g (f xs) = f (map g xs)

Zawiera wszystkie funkcje g :: tau -> tau', wszystkie listy xs :: [tau] i wszystkie funkcje polimorficzne f :: [a] -> [a]. Zasadniczo ta równość stwierdza, że f może tylko zmienić kolejność elementów swojej listy argumentów lub upuścić lub powielić elementy, ale nie może wymyślać nowych elementów.

Być szczerze mówiąc, może wymyślać elementy, ponieważ może "wstawić" niekończący się błąd obliczeniowy/run-time Do List, ponieważ typ błędu jest polimorficzny. Oznacza to, że równość ta łamie się już w języku programowania takim jak Haskell Bez seq. Poniższe definicje funkcji stanowią przeciwny przykład równania. Zasadniczo po lewej stronie g "ukrywa" błąd.

g _ = True
f _ = [undefined]

Aby naprawić równanie, g musi być ścisłe, czyli musi odwzorować błąd na błąd. W tym przypadku równość utrzymuje się ponownie.

Jeśli dodamy operator polimorficzny seq, równanie ponownie się rozpada, na przykład następująca instancja jest przykładem licznika.

g True = True
f (x:y:_) = [seq x y]

Jeśli weźmiemy pod uwagę listę xs = [False, True], mamy

map g (f [False, True]) = map g [True] = [True]

Ale z drugiej strony

f (map g [False, True]) = f [undefined, True] = [undefined]

Oznacza to, że możesz użyć seq, aby element pewnej pozycji listy zależał od definicji innego elementu na liście. Równość występuje ponownie, jeśli g jest całkowita. Jeśli interesują Cię wolne twierdzenia, sprawdź generator wolnych twierdzeń , który pozwala Ci określić, czy rozważasz język z błędami, czy nawet język z seq. Chociaż może się to wydawać mniej praktyczne, seq przerywa pewne przekształcenia, które są używane do poprawy wydajności programów funkcjonalnych, na przykład, foldr/build fuzja kończy się niepowodzeniem w obecności seq. Jeśli interesuje cię więcej szczegółów na temat twierdzeń wolnych w obecność seq, przyjrzyjmy się swobodnym twierdzeniom w obecności seq .

Z tego, co wiem, było wiadomo, że polimorficzny seq łamie pewne przekształcenia, gdy został dodany do języka. Jednak althernatives mają również wady. Jeśli dodasz klasę typową seq, Być może będziesz musiał dodać wiele ograniczeń klas typowych do swojego programu, jeśli dodasz seq gdzieś w głębi. Co więcej, nie było wyboru, aby pominąć seq, ponieważ już wiadomo, że istnieją wycieki przestrzeni, które można naprawić za pomocą seq.

Wreszcie, mogę coś przegapić, ale nie widzę, jak by działał seq operator typu a -> a. Podpowiedź seq jest taka, że ewaluuje wyrażenie do postaci normalnej head, jeśli inne wyrażenie jest ewaluowane do postaci normalnej head. Jeśli seq mA typ a -> a, nie ma możliwości uzależnienia oceny jednego wyrażenia od oceny innego wyrażenia.

 49
Author: Jan Christiansen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-09 13:53:37

Kolejny kontrprzykład jest podany w tej odpowiedzi - monady nie spełniają praw monad z seq i undefined. A ponieważ undefined nie można uniknąć w języku Turinga, winą jest seq.

 8
Author: Petr Pudlák,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:49