2017-11-18 51 views
3

'aa'から 'zz'までの文字列をリストで取得する方法は? 私はそれが明らかであることは知っていますが、そのような問題を解決するための適切なイディオムはわかりません。具体的な例を示してみましょう。おかげさまで 文字列 'aa'、ab 'を' yz '、' zz 'まで取得する方法は?

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

をしようとしましたが、それはコンパイルされません。

+5

リストの内包表記を使用しないのはなぜ? '[[x、y] | –

+5

'(++)'は入力リストとしないので不要です。文字。例えば。 'liftA(\ x y - > [x、y])'は望ましい動作をします。将来参照するために、コンパイルされないコードがある場合は、実際に取得するエラーを含めてください。 – user2407038

+1

'([x] ++ [y] |)で'(++) 'を動作させることができます。 x < - ['a' .. 'z']、y < - ['a' .. 'z']] ' – RoadRunner

答えて

6

これらのすべては、(String = [Char]を覚えている)あなたがやりたいこと:あなたが(++) :: Char -> Char -> [Char]を必要とするので

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

は動作しません

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 

理由ですが、あなただけ(++) :: [Char] -> [Char] -> [Char]を持っています。あなたはシングルトンリストにChar Sを入れて、物事が仕事を得るために(++)に引数の上returns秒で投げることができます。

(. return) . (++) . return <$> ['a'..'z'] <*> ['a'..'z'] 
関連する問題