Data.HashTable を使ってみる

Data.HashTable を使ってみます。

> :m + Data.HashTable
-- (==)       : 比較する関数
-- hashString : Hash 値を計算する関数
>  h <- new (==) hashString :: IO (HashTable String [(Int,String)])
-- 適当なキーで適当な値を入れてみる。
> insert h "abc" [(123,"456")]

> Data.HashTable.lookup h "abc"   --=> Just [(123,"456")]
> Data.HashTable.lookup h "abcf"  --=> Nothing

> insert h "taro" [(100,"chiba")]
> Data.HashTable.lookup h "taro"  --=> Just [(100,"chiba")]

-- 値を更新してみる。
> update h "abc" [(123,"japan")]    --=> True
> update h "abc---" [(123,"japan")] --=> False

> Data.HashTable.lookup h "abc"     --=> Just [(123,"japan")]

-- リストにしてみる。更新に失敗したのは新しく登録されている。
> toList h
--=> [("abc---",[(123,"japan")]),("abc",[(123,"japan")]),("taro",[(100,"chiba")])]

-- リストから HashTable を作ってみる。
> hash <- fromList hashString [("taro","chiba"),("hanako","tokyo")]

> Data.HashTable.lookup hash "hanako"
--=> Just "tokyo"
> toList hash
--=> [("taro","chiba"),("hanako","tokyo")]

関数型言語っぽくないですけど便利そうです。
new の型

Prelude Data.HashTable> :t new
new
     -- 同じ型の二つの値を比較してBool値を返す関数
  :: (key -> key -> Bool)
     -- key から Hash を算出する関数
     -- Int 用 : hashInt、文字列用: hashString
     -> (key -> GHC.Int.Int32) 
     -> IO (HashTable key val) --

作成される HashTable の型を指定しないとデータを追加できない。

>  h <- new (==) hashString
> insert h "foo"  (100,"var")

<interactive>:1:16:
    Couldn't match expected type `GHC.Prim.Any'
           against inferred type `(t, [Char])'
    In the third argument of `insert', namely `(100, "var")'
    In the expression: insert h "foo" (100, "var")
    In the definition of `it': it = insert h "foo" (100, "var")

>  h <- new (==) hashString :: IO (HashTable String (Int,String))
> insert h "foo"  (100,"var")
> toList h     --=> [("foo",(100,"var"))]

紫藤のページ/ Haskell のお勉強 / 10. 種々のデータ構造 / 6. HashTable を参考にしました。