1.概略
前の記事で再帰関数を求める問題を出したが、ここではその回答を示す。回答は一つだけでなく複数あるので、ここで示す回答はその一例だと思ってほしい。
なお、それぞれの関数には型シグネチャもつけた。
問題1:リストから先頭の要素を散り除く関数tail'を作成せよ。
tail' :: [a] -> [a] tail' [] = error "No list." tail' (_:xs) = tail1 xs where tail1 [] = [] tail1 (y:ys) = y : tail1 ys
このプログラムでは、先頭の要素を取り除いた後、tail1を呼ぶが、その記述はwhereをつけてその後に記した。また、_のところは、変数、例えば、nが入るが、その変数名は使われることがないので、無名の変数にしてある。以下でも同じである。
問題2:リストから最後の要素を散り除く関数init'を作成せよ。
init' :: [a] -> [a] init' [] = error "No List." init' [_] = [] init' (x:xs) = x : init' xs
問題3:リストの長さを求める関数length'を作成せよ。
length' :: [a] -> Int length' [] = 0 length' (_:xs) = 1 + length' xs
問題4:リストからn番目の要素を取り出す関数nthを作成せよ。
nth :: Int -> [a] -> a nth _ [] = error "Short List" nth 1 (x:_) = x nth n (_:xs) = nth (n - 1) xs
リストの最初の要素を1番目と考えてプログラムを作成した。0番目と考える場合には修正する必要がある。
問題5:あるリストの最初からn番目までをそっくり取りだした部分リストを得る関数take'を作成せよ。
take' :: Int -> [a] -> [a] take' _ [] = [] take' 1 (x:_) = [x] take' n (x:xs) = x : take' (n - 1) xs
問題6:文字列からブランクを取り除く関数removeBlankを作成せよ。
removeBlank :: String -> String removeBlank [] = [] removeBlank (x:xs) | x == ' ' = removeBlank xs | otherwise = x : removeBlank xs
上記のプログラムでStringは[Char}の言い換えである。
問題7:リストから要素xと要素yを取り除く関数remove'を作成せよ。
remove' :: (Eq a) => a -> a -> [a] -> [a] remove' _ _ [] = [] remove' x y (z:zs) | x == z || y == z = remove' x y zs | otherwise = z : remove' x y zs
問題8:数列から偶数を取り除く関数removeEvenを作成せよ。
removeEven :: [Int] -> [Int] removeEven [] = [] removeEven (x:xs) | mod x 2 == 0 = removeEven xs | otherwise = x : removeEven xs
問題9:リストを反転させる関数reverse'を作成せよ。
reverse' :: [a] -> [a] reverse' [] = [] reverse' (x:xs) = reverse xs ++ [x]
問題10:リストが与えられた時、両端の要素を除いた部分リストを反転させる関数reverse1を作成せよ。
reverse1 :: [a] -> [a] reverse1 [] = error "No List." reverse1 [_] = error "Short List" reverse1 (_:xs) = reverse1' xs where reverse1' [_] = [] reverse1' (y:ys) = reverse1' ys ++ [y]