Haskell 遊び
リストのインデックス n 番目を置き換える
replace 関数。文字列(というかリストなら何でもいい)の n 番目(0 番が最初)を chr で置き換える。
main = print $ replace "Hallo!!" 1 'e' replace :: [a] -> Int -> a -> [a] replace st n chr = take n st ++ [chr] ++ drop (n + 1) st
出力。
"Hello!!"
リストの要素 a を b で置き換える
gsub 関数。文字列(というか、リストなら何でもいい)内の a をすべて b に置き換える。
main = print $ gsub "Herro!!" 'r' 'l' gsub :: Eq a => [a] -> a -> a -> [a] gsub st a b = map (change a b) st change :: Eq a => a -> a -> a -> a change a b n = if n == a then b else n
出力。
"Hello!!"
配列の間に配列を挟む
関数 hasamu (笑)。hasamu a b で配列 a の要素の間に配列 b を挟んで出力。
main = putStrLn $ hasamu "Haskell" ".." hasamu :: [a] -> [a] -> [a] hasamu a b = head a : f (tail a) where f as = if null as then [] else b ++ [head as] ++ f (tail as)
出力。
H..a..s..k..e..l..l
こんなのも。
main = putStrLn $ concat $ hasamu ["Ruby", "Go", "Haskell"] ["\n"] Ruby Go Haskell
ふつうに Int で。
main = print $ hasamu [1..10] [0, 0] [1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,9,0,0,10]
無限リストで。こういうのは Haskell すごいよなあ。どうなっているのだろう。
main = print $ take 21 $ hasamu [100..] [0] [100,0,101,0,102,0,103,0,104,0,105,0,106,0,107,0,108,0,109,0,110]
つーか、Ruby の
10.times {|i| puts i + 1}
が Haskell でどうやったらよいのかわからなかったので、苦し紛れに
main = putStrLn $ concat $ hasamu (map show [1..10]) ["\n"]
としてみた。何か Haskell むずかしすぎるのですけれど。いや待てよ、
main = putStr $ unlines $ map show [1..10]
これでいいや。失礼しました。
でもこの関数 hasamu って、事前に用意されているよね、たぶん。
モジュール化
Hasamu.hs
module Hasamu (hasamu) where hasamu :: [a] -> [a] -> [a] hasamu a b = head a : f (tail a) where f as = if null as then [] else b ++ [head as] ++ f (tail as)
GHCi で。
$ ghci GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help Prelude> :l Hasamu.hs [1 of 1] Compiling Hasamu ( Hasamu.hs, interpreted ) Ok, modules loaded: Hasamu. *Hasamu> hasamu "Haskell" ".." "H..a..s..k..e..l..l" *Hasamu> putStrLn $ concat $ hasamu ["Ruby", "Go", "Haskell"] ["\n"] Ruby Go Haskell *Hasamu> hasamu [1..10] [0, 0] [1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,9,0,0,10] *Hasamu> take 21 $ hasamu [100..] [0] [100,0,101,0,102,0,103,0,104,0,105,0,106,0,107,0,108,0,109,0,110] *Hasamu> :q Leaving GHCi.
本にある「:m + Hasamu」ではダメみたい。「:l Hasamu.hs」でロードする(参照)。
.hs ファイルでならふつうに import すれば可能。
import Hasamu main = putStrLn $ show $ take 21 $ hasamu [100..] [0]