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]