むずかしめのパソコン勉強の記録

計算機科学とか関数型言語とか

Haskell H99 Question 15

http://www.haskell.org/haskellwiki/99_questions/11_to_20
Problem 15
日本語訳

与えられた数字の回数だけリストの各要素を複製しなさい。
> repli "abc" 3
"aaabbbccc"

repli :: [a] -> Int -> [a]
repli xs y = concatMap (\x -> replicate y x) xs

repli' xs y = xs >>= (\x -> replicate y x) 

replicateを使ってdupliと同じことをしました。
ついでにListモナドの練習も、dupliで作成したものと同じ形で練習として作成。

模範解答
http://www.haskell.org/haskellwiki/99_questions/Solutions/15

repli :: [a] -> Int -> [a]
repli xs n = concatMap (take n . repeat) xs

repeat関数とtake関数を使っています。

repeatは、引数で取ったaの無限リストを作るようですね。すごい関数だな。
こんな関数をサポートできるのは遅延評価がしっかりサポートされているHaskellだけなんでしょうね。

*Main> :t repeat
repeat :: a -> [a]

takeは、自然数nとリストを引数にして、リストの最初のn要素だけだけを取り出したリストを返します。

これを合成するとあるaの無限配列からn分だけを取り出したリストを取得できます。

*Main> :t \n -> take n . repeat
\x -> take n . repeat :: Int -> a -> [a]

*Main> (\n -> take n . repeat) 3 'a'
"aaa"