12
votes

Calculer le produit Cartésien N-Ary

donné deux listes, je peux produire une liste de toutes les permutations le produit cartésien de ces deux listes: xxx

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) xxx

Je n'ai pu trouver quoi que ce soit de pertinence sur howogle .. La seule fonction correspondant à la signature était transpose , qui ne produit pas la sortie souhaitée.

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?


0 commentaires

6 Réponses :


22
votes
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]]

3 commentaires

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 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 exactement cela fonctionne



3
votes

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


1 commentaires

Cela peut être légèrement simplifié en éliminant une concaténation superflue dans k m m '= ConcaTMap (\ x -> carte (x :) m') m . Pourrait aussi l'écrire comme une compréhension de liste comme [x: xs | x <- M, XS <- M '] .



6
votes

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: xxx

ou avec plus de "noms haskell-y", noms de paramètres sans signification;) xxx

Cela vale d'être assez similaire à SCLV posté après tout.


1 commentaires

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 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 en général).



2
votes

Si vous souhaitez avoir plus de contrôle sur la sortie, vous pouvez utiliser une liste comme fonction d'application, par exemple: xxx

disons que vous voulez une liste de tuples à la place: xxx

et il a l'air un peu cool, aussi ...


0 commentaires

4
votes

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 ]


0 commentaires

1
votes

Vous pouvez le faire de 2 façons:

  1. Utilisation de la compréhension de la liste li> ol>
      cp1 :: [[a]] -> [[a]]
      cp1 xs = foldr f [[]] xs
            where f xs xss = [x:ys | x <- xs, ys <- xss]
    


0 commentaires