(++) :: [a] -> [a] -> [a] (x:xs) ++ ys = x : (xs ++ ys) [] ++ ys = ys
3 Réponses :
La récursion de la queue garderait la constante de la pile, mais dans une langue stricte, le tas augmenterait comme x: (xs ++ ys) code> a été calculé. Dans HASKELLL, car il est non strict,
x code> serait libéré avant que la valeur suivante ait été calculée (sauf si l'appelant détenait une référence à
x code> inutilement), donc le tas aussi em> être constant. p>
N'oubliez pas que c'est-à-dire, Lorsque le code client est consommant em> la liste liée, il le décompose dans une tête et une queue (par exemple, Lorsque votre code est construisant em> la liste liée, en raison de l'évaluation paresseuse, tout ce qu'il doit faire est de retourner un thunk em> ou de promettre qu'il retournera une liste liée lorsque demandé. Lorsque la tête est déréférencée, elle est fournie à la demande et la queue est laissée comme une promesse pour le reste de la liste. P>
Il devrait être facile de voir que tant que la liste n'est pas copiée ou autrement stockée, chaque Thunk sera utilisé une fois, puis rejeté, de sorte que l'espace de stockage global soit constant. P>
De nombreuses langues strictes exposent un mécanisme (souvent appelé un générateur em>) pour accomplir le même type de génération de liste paresseuse, mais avec une évaluation paresseuse, de telles caractéristiques sont "gratuites" dans le cadre de la langue - En substance, toutes les listes de haskell sont des générateurs! p> "foo" code> est juste du sucre syntaxique pour
'F': 'O': 'O': [] p>.
string code> est juste un alias pour
[caractère] code> qui n'est qu'une liste liée des caractères. P>
x: xs code>), fait quelque chose avec la tête (si désiré ), puis recute pour la queue. P>
S'appuyant sur l'évaluation paresseux plutôt que sur la récursion de la queue est une caractéristique de HASKELLL par rapport à d'autres langues PF. Les deux rôles liés au jeu en termes de limitation de la mémoire; Lequel est le mécanisme approprié dépend des données produites. P>
Si votre sortie peut être consommée progressivement, vous devriez préférer tirer parti de l'évaluation paresseuse, car la sortie ne sera générée que si nécessaire, limitant ainsi la consommation de tas. Si vous construisez avec impatience la sortie, vous vous démissez à l'aide de tas, mais vous pouvez au moins conserver la pile en étant récursif de queue. P>
Si votre sortie ne peut pas être consommée progressivement - vous êtes peut-être calculé un Donc, si vous êtes impatient, vous risquez de perdre des tas bâtiment em> une grande structure de données. Si vous êtes paresseux, vous risquez de différer SIMPLIFICIFICATION EM> (par exemple, réduction Pour jouer avec les deux côtés de la pièce, réfléchissez int code> - alors la paresseux peut vous laisser avec une pile indésirable de thunks dont l'évaluation va souffler votre pile. Dans ce cas, un accumulateur strict et une récursion queue sont appelés. P>
1 + 1 code> à
2 code>) sur le tas, seulement pour finalement souiller votre pile quand Payer le Piper. P>
pli " code> et
replier code>. p>
Cela me semble que l'espace constant i> vient de jeter
x code> lors de la génération du prochain
xs code> sur demande.