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