2017-11-18 1 views
3

Wie erhalten Sie Strings von 'aa' bis 'zz' in einer Liste? Ich weiß, es ist offensichtlich, aber kenne nicht die richtige Sprache, um diese Art von Problemen zu lösen. Zeigen Sie die Idee mit konkreten Beispielen und ich finde den Rest heraus. Danke.Wie erhält man Strings 'aa', ab 'bis' yz ',' zz '?

Versuchte
(++) <$> ['a'..'z'] <*> ['a'..'z'] 

aber nicht kompiliert.

+5

Warum nicht eine Liste Verständnis verwenden? '[[x, y] | x <- ['a' .. 'z'], y <- ['a' .. 'z']] ' –

+5

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

+1

Sie können '(++)' hier mit '[[x] ++ [y] | x <- ['a' .. 'z'], y <- ['a' .. 'z']] ' – RoadRunner

Antwort

6

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'] 
Verwandte Themen