Il est plus facile d'expliquer cela avec un exemple:
Je veux écrire une fonction [a] -> [(a, a)] donc si j'obtiens une liste
function s = [(x,y) | x <- s, y <- s]
4 Réponses :
Solution utilisant la récursivité:
[(head x, y) | x <- tails xs, y <- x]
Sans récursivité:
import Data.List (tails) f'' :: [a] -> [(a, a)] f'' xs = concatMap (\sl -> zip (repeat $ head sl) sl) (tails xs)
Sans compréhension de liste:
import Data.List (tails) f' :: [a] -> [(a, a)] f' xs = concat [[(head x, y) | y <- x] | x <- tails xs]
Pourquoi concat
alors que vous êtes déjà dans une compréhension de liste? f 'xs = [(tête x, y) | x <- tails xs, y <- x]
. Et puis la prochaine question évidente est: pourquoi utiliser head
lorsque la correspondance de motifs fera l'affaire? f 'xs = [(h, y) | x @ (h: _) <- tails xs, y <- x]
.
Ce serait mieux, d'accord, même si je pense que l'utilisation de head
est bien.
Poursuivant l'idée du filtre [(x, y) | x , vous pouvez le faire en utilisant foldl à la place:
f = foldl add []
where add ys (a,b) | notElem (b,a) ys = (a,b):ys
| otherwise = ys
g xs = [(x,y) | x <- xs, y <- xs]
function = f . g
Vous pouvez utiliser scanr
f l = zip l (scanr (:) [] l) >>= \(h,t) -> fmap ((,) h) t
Vous obtenez d'abord la liste des (têtes, queues) de l
, les queues de carte appariant leurs éléments avec la tête correspondante et enfin aplatir tout.
C'est une boucle imbriquée.
import Data.List (dropWhile) com xs = do x <- xs y <- dropWhile (/= x) xs return (x, y)
Quelle est la sortie pour
[A, A, A, A]
?Je pense que cela implique que les éléments sont uniques (conceptuellement un ensemble).