J'essaie de faire une fonction relativement simple qui est presque concessue mais avec une petite torsion. C'est censé être binaire ou ensemble les derniers et premiers éléments de chaque liste et les combiner dans le processus. Je travaille à apprendre à écrire du code capable de tirer parti des capacités de fusion de flux dans data.list.stream
J'ai vérifié que la concession de base fait ce qui est nécessaire et construit la liste paresseusement, cependant, cette version que j'ai créée. ne le fait pas. Dans la base, Concat est spécifié comme suit: p> voici mon code: p> La question que j'ai est, Comment puis-je écrire cela pour que la liste soit construite paresseuse? J'ai même essayé d'écrire Bappend en mimage de la définition (++) à la base, mais cela n'a pas fait de différence. P> Pour le moment, j'utilise le code suivant, cela fonctionne comme je le souhaite, mais la performance tombe derrière Concat. En outre, il utilise une récursion explicite que j'aimerais éviter. P> Donc, la question que j'ai est, comment puis-je écrire ce code afin qu'il construit la liste paresseusement et sans récursion explicite? p> Merci pour votre temps. p> Mon intérêt principal, pour le moment, faire Code propre, concis et ossature avec les combinaisons standard. Je suis toujours très débutant avec la pensée fonctionnelle et j'aimerais voir une façon raisonnablement efficace de les mettre à utiliser ici. P> p>
3 Réponses :
Vous semblez avoir une faute de frappe, 'Bapennd' devrait être "Bappend" dans le premier extrait. Et je pense que "combiner" dans le dernier extrait devrait être "Bconcat".
On dirait que le premier (rabair1 Bappend) sera assez paresseux. Pourriez-vous élaborer sur le manque de paresse? P>
comme pour avoir besoin de "Derniers xs" et de "Derniers Xs" en même temps, vous pouvez souhaiter une seule traversée de XS: P>
let un [] = error "no last element" un (x:[]) = ([],x) un (x:xs) = let (ys,z) = un xs in (x:ys,z)
Merci, j'ai corrigé les tybes. Manque de paresse comme en mangeant toute la mémoire dans mon système, causée par avoir à rendre la chaîne entière en mémoire avant que tout autre code ne puisse rien faire avec elle. Toute l'idée est de faire fonctionner ce programme en mémoire constante.
J'ai essayé d'utiliser votre fonction ONU pour avoir la tête et la queue en même temps, mais cela a fini par ralentir le code. Je soupçonne que cela a quelque chose à voir avec l'optimisation des flux de fusion que j'utilise. Ce "dernier XS" détenant la référence explique pourquoi je reçois une légère amélioration de la performance pour rendre le premier paramètre au bappend que j'utilise actuellement, strict.
Votre définition semble stricte pour moi. Par exemple, essayez d'évaluer
bconcat [] = error "bconcat: empty outer list" bconcat (xs:xss) = loop xss xs where loop [] ys = ys loop ((x:xs):xss) [y] = let z = x .|. y in seq z $ z : loop xss xs loop ([]:_) _ = error "bconcat: empty inner list" loop xss (y:ys) = y : loop xss ys
Je ne suis pas sûr de la sorte de mes définitions de bconcat que vous vouliez essayer de "longueur $ bconcat [[[1,2,3], [4, non définie, 6]]" avec mais cela revient 5 dans les deux cas, comme je m'attendais.
Merci pour la version fusionnée de Bconcat. Ce code vole vraiment. C'est encore plus rapide que le concat ordinaire. Le programme que j'essaie d'optimiser les courses 40% plus rapidement avec celui-ci.
ACK, qui est cassé: "BCONCAT [[[1], [2], [4]]" donne "[3 *** exception: /tmp/foo.hs:(5,9)-(8,41): Motifs non exhaustifs en boucle de fonction "
Oui, je l'ai résolu pour mon propre code en ajoutant un cas particulier pour le moment où la nouvelle liste n'a qu'un élément. Il ressemble à ceci: boucle (x: []): XSS) [Y] = let z = x. |. y dans seq z $ boucle xss [z] code>
Je peux changer la réponse en augmente plus près du problème d'origine en écrivant: Le ci-dessus ignore toutes les listes internes vides. P> P>
Merci, mon code actuel n'a pas besoin de gérer des listes internes vides mais cela pourrait être utile à un autre but.
Je devinerais que le problème est que vous devez évaluer toute la première liste avant de pouvoir être capable de le faire. IMHO Il n'y a pas d'évaluation paresseuse possible.
Il y a définitivement un moyen de faire construire la liste résultante paresseusement. Concat réussit à cela et cela fait presque la même chose. En outre, le dernier extrait que j'ai posté est le faire comme je le veux. Cela n'a tout simplement pas atteint le niveau de performance de Concat.
Je vois la différence, la première version ou 'enfin (en dernier) avec le re
Je vois la différence, considérez BCONCAT sur [[1], [2], [4], [8,0]] qui est [15]. Le pliard1 calcule (1.. La tête [14]) par premier calcul [14] = repli1 [[2], [4], [8]] et ainsi de suite. La deuxième version calcule Bappend [[3], [4], [8]] alors Bappend [[7], [8]].