FunDepでCollectionクラス

30分プログラム、その400。この前のocaml-nagoyaid:syd_sydさんがFunDepの話をしていた。

細かい話はついていけなかった。でも、例としてでてきたCollクラスがなかなか便利そうだった。

class Coll a b where
    empty  :: b
    insert :: a -> b -> b

instance Coll a [a] where
    empty = []
    insert = (:)	      

なのでSetとかMapなどの他のデータ構造にも対応させてみた。Arrayでinsertを実現するのは面倒そうだし、あまり嬉しくなさそうだったのでパス。

使い方

*Main> insert 42 empty :: [Int]
[42]

*Main> insert 42 empty :: Set.Set Int
fromList [42]

*Main> insert ("answer",42) empty :: Map.Map String Int
fromList [("answer",42)]

*Main> insert 42 empty :: Seq.Seq Int
fromList [42]

ソースコード

{-# OPTIONS -XMultiParamTypeClasses -XFunctionalDependencies -XFlexibleInstances #-}
import qualified Data.Set as Set
import qualified Data.Map as Map
import qualified Data.Sequence as Seq

class Collection a b | b -> a where
    empty  :: b
    insert :: a -> b -> b

instance Collection a [a] where
    empty  = []
    insert = (:)

instance (Ord a) => Collection a (Set.Set a) where
    empty = Set.empty
    insert = Set.insert

instance (Ord k) => Collection (k,a) (Map.Map k a) where
    empty  = Map.empty
    insert (key,a) map = Map.insert key a map

instance Collection a (Seq.Seq a) where
    empty  = Seq.empty
    insert = flip (Seq.|>)