me pregunto por qué¿Por qué s ++ t no lleva a un desbordamiento de pila para s grande?
Prelude> head $ reverse $ [1..10000000] ++ [99]
99
no conduce a un error de desbordamiento de pila. La ++ en el preludio parece sencillo y no recursiva de cola:
(++) :: [a] -> [a] -> [a]
(++) [] ys = ys
(++) (x:xs) ys = x : xs ++ ys
EDIT: Al principio, pensé que el problema tiene algo que ver con la forma ++ se define en el preámbulo, en especial con la reescritura reglas, por lo tanto la pregunta continuó como abajo. La discusión me mostró que este no es el caso. Ahora creo que un efecto de evaluación lento provoca que el código se ejecute sin un desbordamiento de pila, pero no entiendo cómo.
Así que solo con esto, debería encontrarse con un desbordamiento de pila, ¿verdad? Así que averiguar es probable que tenga algo que ver con la magia GHC que sigue la definición de ++:
{- # REGLAS "++" [~ 1] forall xs ys. xs ++ ys = aumento (\ c n -> foldr c n xs) ys # -}
* ¿Eso es lo que ayuda a evitar el desbordamiento de la pila? ¿Podría alguien dar alguna pista de lo que está sucediendo en este código? **
Las reglas de reescritura no se activan en el intérprete (a menos que las habilite). –
@Don: Gracias, no los tuve habilitados. De todos modos, debería haber comprobado esto antes de escribir: una nueva función "fst = si s == [] luego t else let (x: ss) = s en x: (f ss t)" tampoco conduce a un desbordamiento de la pila, por lo que no puede tener nada que ver con la parte REGLAS ... – martingw