donné deux listes, je peux produire Comment prolonger le permanent de sorte que Prendre deux listes, il prend une liste (longueur n) des listes et renvoie une liste de listes (longueur n) p> Je n'ai pu trouver quoi que ce soit de pertinence sur howogle .. La seule fonction correspondant à la signature était EDIT: Je pense que la version à 2 listes de ceci est essentiellement le Produit cartésien , mais je ne peux pas envelopper ma tête autour de la mise en œuvre de la Produit cartésien N-Ary . Tous les pointeurs? P> p> transpose code>, qui ne produit pas la sortie souhaitée. p>
6 Réponses :
Prelude> sequence [[1,2],[3,4],[5,6]] [[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
Bien que la séquence résolve le problème, j'étais vraiment intéressé par la manière dont cela fonctionnerait. Mise en œuvre utilise des monades; Existe-t-il un moyen de calculer le produit sans utiliser de monades? (par exemple dans une langue qui n'inclut pas les monades)
@ Bleum937: Pour la liste Monad, Séquence Code> signifie "pour chaque élément de la première liste, la compare à chaque liste obtenue en séquençant les listes restantes". C'est fondamentalement le moyen le plus évident d'écrire un produit cartésien à l'aide d'un pli droit.
Upvote ceci est que vous nous avez dit comment i> exactement cela fonctionne
En complément de la réponse de Jleedev (ne pouvait pas formater cela dans les commentaires):
Une substitution rapide non cochée de fonctions de liste pour les monadiques: p>
sequence ms = foldr k ([[]]) ms where k m m' = concatMap (\x -> concatMap (\xs -> [x:xs]) m') m
Cela peut être légèrement simplifié en éliminant une concaténation superflue dans k m m '= ConcaTMap (\ x -> carte (x :) m') m code>. Pourrait aussi l'écrire comme une compréhension de liste comme
[x: xs | x <- M, XS <- M '] code>.
J'ai trouvé l'article d'Eric Lippert sur Produit cartésien informatique avec Linq tout à fait utile pour améliorer ma compréhension de ce qui se passait. Voici une traduction directe plus ou moins: ou avec plus de "noms haskell-y", noms de paramètres sans signification;) p> Cela vale d'être assez similaire à SCLV posté après tout. P> p>
C'est la même chose que celle de SCLV, en fait, jusqu'à quelques différences de syntaxe. En outre, vous savez ceci (après avoir écrit la traduction), mais pour quelqu'un d'autre: Notez que l'exemple d'Eric Lippert utilise un pli gauche i> au lieu d'un pli droit, mais cela ne fait aucune différence car la fonction est stricte dans Les épines des listes de toute façon (comme avec la séquence code> code> en général).
Si vous souhaitez avoir plus de contrôle sur la sortie, vous pouvez utiliser une liste comme fonction d'application, par exemple: disons que vous voulez une liste de tuples à la place: P> et il a l'air un peu cool, aussi ... p> p>
Voici ma façon de la mettre en œuvre simplement, en utilisant uniquement des compréhensions de liste.
crossProduct :: [[a]] -> [[a]] crossProduct (axis:[]) = [ [v] | v <- axis ] crossProduct (axis:rest) = [ v:r | v <- axis, r <- crossProduct rest ]
Vous pouvez le faire de 2 façons:
cp1 :: [[a]] -> [[a]] cp1 xs = foldr f [[]] xs where f xs xss = [x:ys | x <- xs, ys <- xss]