Z powodu lenistwa (plus ograniczenie monomorfizmu & sztylet;). Zasadniczo, gdy mówisz
year = year + 1
a następnie ocenić year
, Haskell oszczędność miejsca dla wyniku, a następnie, gdy widzi year
próbuje ponownie wykorzystać ten sam rezultat. Więc kiedy year + 1
próbuje ocenić year
, kod dla year
nie jest faktycznie wprowadzany.
W GHC, do implementacji wielowątkowości & ddagger;, to, co faktycznie robi, blokuje bieżący wątek, gdy próbuje uzyskać wartość zmiennej, która jest już oceniana. Następnie, po zakończeniu oceny, wznawia wykonywanie zablokowanego wątku. W tym przypadku wątek jest blokowany podczas oceny, którą sam wykonuje, dlatego pojawia się zakleszczenie.
Jeśli zamiast powiedzieć
year() = year() + 1
następnie uruchomiony year()
daje przepełnienie stosu dla mnie.
& sztylet; Ograniczenie monomorfizm wchodzi w grę, ponieważ jeśli dodać podpis TYP
year :: Num a => a
year = year + 1
kompilator jest całkowicie wolny w leczeniu słownika takiego parametru ()
Num a
, otrzymując przepełnienie stosu. W tym przypadku nie stanowi to problemu, ale nie buforowanie wyników pośrednich jest dużym problemem w rzeczywistych obliczeniach. W tym przypadku wygląda na to GHC jest faktycznie oddanie rekursji wewnątrz abstrakcję nad słowniku, produkując kod bardziej jak
year() = let y = y + 1 in y
który również nie powoduje przepełnienie stosu.
& ddagger; kompilacji kodu (z GHC) w trybie jednowątkowy daje
<<loop>>
co oznacza GHC wykryte nieskończoną pętlę, i postanowił skarżą się na niego.
Obserwuj użycie pamięci. To zależy od optymalizacji, ale to jedna rzecz, która może się zdarzyć. – luqui
Jakie są rzekome wyniki? –
Zakładam, że wynik tego jest nieokreślony. –