問題1:自然数のリスト[1,2..]より各要素を5だけ増やしたリストを作成する。即ち、[6,7..]を作成する。
答
Prelude> take 10 $ map (+5) [1,2..] [6,7,8,9,10,11,12,13,14,15]
問題2:自然数のリスト[1,2..]より各要素を二乗したリストを作成する。
答
Prelude> take 10 $ map (\x -> x * x) [1,2..] [1,4,9,16,25,36,49,64,81,100]
問題3:自然数のリスト[1,2..]より3の倍数のリストを作成する。
答
Prelude> take 10 $ map (*3) [1,2..] [3,6,9,12,15,18,21,24,27,30]
問題4:アルファベットだけからなる文字列を得て、各文字を一つ後の文字に変更した文字列を出力する。但し、z,Zの後の文字は、それぞれa,Aとする。
答:Haskellでは、ifによって場合分けする時は、if .. then .. elseを用いる。
Prelude> map (\x -> if x == 'z' then 'a' else if x == 'Z' then 'Z' else succ x) "AdeTEfzyjZawrTKI" "BefUFgazkZbxsULJ"
問題5:リストが与えられた時、各要素に対して、自分とそれに続く要素を対にしたリストを作成する。例えば、[1,2..]は、[(1,2),(2,3),(3,4)…]となる。
答:無限のリストを前提にする(有限の場合には、最後の対を求める時に特別な処理が必要)。次のプログラムはトリッキーである。無限のリストlstを受け取り、これから、これを最初の要素とし、さらに、これから最初の要素を除いたリストを二番目のリストとし、同じように、最初の要素を取り除いたリストを次の要素とするリストlistofLists \ lstを作成する。このように、無限リストの無限リストを作成するようなことはHaskell以外の言語では難しい。
Prelude> let listOfLists lst = lst : listOfLists (tail lst) Prelude> take 10 $ map (\x -> (head x, head $ tail x)) (listOfLists [1,2..]) [(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(8,9),(9,10),(10,11)]
問題6:数のリストが与えられた時、各要素に対して、自分とそれに続く要素とを足したリストを作成する。
Prelude> let listOfLists lst = lst : listOfLists (tail lst) Prelude> take 10 $ map (\x -> (head x + (head $ tail x))) (listOfLists [1,2..]) [3,5,7,9,11,13,15,17,19,21]
問題7:リストが与えられた時、大文字を小文字に変更したリストを作成する。
答:関数toSmallを用意する。
toSmall :: Char -> Char toSmall a | a `elem` capital = getSmall' a pair | otherwise = a where small = ['a'..'z'] capital = ['A'..'Z'] pair = zip small capital getSmall' :: Char -> [(Char, Char)] -> Char getSmall' _ [] = error "A Small letter does not exist." getSmall' a' ((ySmall, yCapital):ys) | a' == yCapital = ySmall | otherwise = getSmall' a' ys
これを用いると次のようになる。
*Main> map toSmall "TOKYO is popular in the WORLD." "tokyo is popular in the world."
問題8:文字列が与えられた時、それぞれの文字を小文字、大文字を区別しないで、アルファベットの順番、例えば、a,Aは1、h,Hは8、に変換したリストを作成する。
答:関数toOrderを用意する。
toOrder :: Char -> Int toOrder a |a `elem` small = getNumber a small |a `elem` capital = getNumber a capital | otherwise = error "It is not an alphabet." where small = ['a'..'z'] capital = ['A'..'Z'] getNumber :: Char -> String -> Int getNumber a' lst = getNumber' a' lst 0 getNumber' :: Char -> String -> Int -> Int getNumber' _ [] _ = error "It is not included in the list." getNumber' a1 (x:xs) n | a1 == x = (+1) n | otherwise = getNumber' a1 xs ((+1) n)
これを用いると次のようになる。
*Main> map toOrder "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ" [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,26,25,26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]
問題9:数字のリストが与えられた時、奇数であれば1に偶数であれば0に変換したリストを作成する。
答
Prelude> map (\x -> if even x then 0 else 1) [3,7,2,6,8,14,63,45] [1,1,0,0,0,0,1,1]
問題10:数字のリストが与えられた時、それぞれを3で割った余りに変換したリストを作成する。
答
Prelude> map (\x -> mod x 3) [3,7,2,6,8,14,63,45] [0,1,2,0,2,2,0,0]