Alle diese tun, was Sie wollen (Sie erinnern sich String = [Char]
):
Control.Monad.replicateM 2 ['a'..'z'] -- Cleanest; generalizes to all Applicatives
sequence $ replicate 2 ['a'..'z'] -- replicateM n = sequenceA . replicate n
-- sequence = sequenceA for monads
-- sequence means cartesian product for the [] monad
[[x, y] | x <- ['a'..'z'], y <- ['a'..'z']] -- Easiest for beginners
do x <- ['a'..'z']
y <- ['a'..'z']
return [x, y] -- For when you forget list comprehensions exist/need another monad
['a'..'z'] >>= \x -> ['a'..'z'] >>= \y -> return [x, y] -- Desugaring of do
-- Also, return x = [x] in this case
concatMap (\x -> map (\y -> [x, y]) ['a'..'z']) ['a'..'z'] -- Desugaring of comprehension
-- List comprehensions have similar syntax to do-notation and mean about the same,
-- but they desugar differently
(\x y -> [x, y]) <$> ['a'..'z'] <*> ['a'..'z'] -- When you're being too clever
(. return) . (:) <$> ['a'..'z'] <*> ['a'..'z'] -- Same as^but pointfree
Der Grund
(++) <$> ['a'..'z'] <*> ['a'..'z']
nicht funktioniert, weil Sie (++) :: Char -> Char -> [Char]
brauchen, aber Sie nur (++) :: [Char] -> [Char] -> [Char]
haben. Sie können in returns
s auf der Argumente (++)
werfen die Char
s in Singleton Listen zu setzen und Dinge an die Arbeit:
(. return) . (++) . return <$> ['a'..'z'] <*> ['a'..'z']
Warum nicht eine Liste Verständnis verwenden? '[[x, y] | x <- ['a' .. 'z'], y <- ['a' .. 'z']] ' –
Sie wollen nicht' (++) 'hier, weil es als Eingänge Listen und nicht dauert Figuren. Z.B. 'liftA (\ x y -> [x, y])' hat das gewünschte Verhalten. Wenn Sie Code haben, der nicht kompiliert wird, schließen Sie den Fehler ein, den Sie tatsächlich erhalten. – user2407038
Sie können '(++)' hier mit '[[x] ++ [y] | x <- ['a' .. 'z'], y <- ['a' .. 'z']] ' – RoadRunner