Zastanawiam się dlaczegoDlaczego s ++ t nie doprowadzić do przepełnienia stosu dla dużych s?
Prelude> head $ reverse $ [1..10000000] ++ [99]
99
nie prowadzi do błędu przepełnienia stosu. ++ w preludium wydaje się proste i non-tail-rekurencyjne:
(++) :: [a] -> [a] -> [a]
(++) [] ys = ys
(++) (x:xs) ys = x : xs ++ ys
EDIT: Początkowo myślałem, że problem ma coś wspólnego ze sposobem ++ jest zdefiniowany w preludium, zwłaszcza z przepisywania zasady, stąd pytanie kontynuowane, jak poniżej. Dyskusja pokazała mi, że tak nie jest. Teraz myślę, że jakiś leniwy efekt oceny powoduje, że kod działa bez przepełnienia stosu, ale nie wiem, jak to zrobić.
Więc po prostu z tym, należy go uruchomić na przepełnienie stosu, prawda? Więc postać to chyba ma coś z magii, który następuje ghc definicję ++
{- # Reguły "++" [~ 1] forall xs ys. XS ++ ys = Augment (\ c n -> foldr c n xs) ys # -}
* Czy to, co pomaga uniknąć przepełnienia stosu? Może ktoś podać kilka podpowiedzi dla tego, co dzieje się w tym kawałku kodu **
Reguły przepisywania nie są uruchamiane w tłumaczu (chyba że je włączysz). –
@Don: Dzięki, nie mam ich włączonych. W każdym razie powinienem to sprawdzić przed wykonaniem pisania: nowa funkcja "fst = jeśli s == [] to t else let (x: ss) = s in x: (f ss t)" również nie prowadzi do przepełnienie stosu, więc nie może mieć nic wspólnego z RULES-part ... – martingw