Haskell入門(標準モジュール)
Data.Listモジュール
リストから重複する要素を取り除いた長さ
import Data.List numUniques :: (Eq a) => [a] -> Int numUniques = length . nub
*Main> numUniques [1,1,2,2,3,1] 3 *Main> nub [1,1,2,2,3,1] [1,2,3]
Data.Listモジュールのインポート
Prelude> :m + Data.List
words
文字列を空白で区切ってリストにする
*Main> words "a bb ccc" ["a","bb","ccc"]
group
リストの要素の、隣接する同じ要素をまとめる
*Main> group [1,2,2,1,1,3] [[1],[2,2],[1,1],[3]]
sort
リストの要素を昇順に並び替える
Prelude Data.List> sort [2,1,4,3] [1,2,3,4]
文字列の中の各単語(スペースで区切られた文字列)の出現回数を求める
Prelude Data.List> "a b a c b" "a b a c b" Prelude Data.List> words it ["a","b","a","c","b"] Prelude Data.List> sort it ["a","a","b","b","c"] Prelude Data.List> group it [["a","a"],["b","b"],["c"]] Prelude Data.List> map (\ws -> (head ws, length ws)) it [("a",2),("b",2),("c",1)]
関数にまとめると
import Data.List wordNums :: String -> [(String, Int)] wordNums = map (\ws -> (head ws, length ws)) . group . sort . words
tails
リストに対してtail関数を繰り返し実行する
*Main Data.List> tails "abc" ["abc","bc","c",""] *Main Data.List> tails [1,2,3] [[1,2,3],[2,3],[3],[]]
isPrefixOf
2つ目のリストが1つ目のリストで始まっているか
*Main Data.List> isPrefixOf "ab" "abc" True *Main Data.List> isPrefixOf "ab" "cabc" False
any
述語とリストを受け取り、リストの中に述語を満たす要素が存在するか
*Main Data.List> any (==2) [1,2,3] True *Main Data.List> any (>4) [1,2,3] False *Main Data.List> any (=='a') "abc" True *Main Data.List> tails "abcd" ["abcd","bcd","cd","d",""] *Main Data.List> any (isPrefixOf "bc") (tails "abcd") True *Main Data.List> any (isPrefixOf "ac") (tails "abcd") False
ある文字列が別の文字列の部分文字列であるか判定する
import Data.List isInList :: (Eq a) => [a] -> [a] -> Bool isInList sand desert = any (isPrefixOf sand) (tails desert)
*Main Data.List> isInList "a" "abc" True *Main Data.List> isInList "b" "abc" True *Main Data.List> isInList "ab" "abc" True *Main Data.List> isInList "bc" "abc" True *Main Data.List> isInList "abc" "abc" True *Main Data.List> isInList "bcd" "abc" False *Main Data.List> isInList "cd" "abc" False *Main Data.List> isInList "d" "abc" False
Data.Charモジュール
シーザー暗号
文字を文字コードに変換 *Main Data.List Data.Char> ord 'a' 97 *Main Data.List Data.Char> map ord "abcxyz" [97,98,99,120,121,122] 文字コードを文字に変換 *Main Data.List Data.Char> chr 97 'a' 文字をシフト *Main Data.List Data.Char> chr $ ord 'a' + 3 'd' *Main Data.List Data.Char> chr $ ord 'b' + 3 'e'
import Data.Char encode :: Int -> String -> String encode offset msg = map (\c -> chr $ ord c + offset) msg decode :: Int -> String -> String decode shift msg = encode (negate shift) msg
*Main Data.List Data.Char> encode 1 "abcxyz" "bcdyz{" *Main Data.List Data.Char> decode 1 it "abcxyz"