haskell - Associated data families and overlapping instances -
i'd 'generic' map data structure can efficiently specialized providing custom instances, in the ghc manual section on type families.
{-# language flexibleinstances #-} {-# language typefamilies #-} {-# language undecidableinstances #-} module mapkey import data.map.strict (map) import qualified data.map.strict map class mapkey k data mmap k :: * -> * instance {-# overlapping #-} mapkey () newtype mmap () v = unitmap (maybe v) instance {-# overlappable #-} ord k => mapkey k newtype mmap k v = ordmap (map k v) sadly, doesn't work. ghc (8.2.1) complains:
conflicting family instance declarations: mmap () = unitmap (maybe v) mmap = ordmap (map k v) | 14 | newtype mmap () v = unitmap (maybe v) | is there language extension allows this? otherwise there way make easy users define 'default' instance ord?
one solution relinquishes overlapping instances use default associated injective type family (quite mouthful). attached methods default implementations default mmap synonym:
{-# language defaultsignatures #-} {-# language typefamilies #-} {-# language typefamilydependencies #-} module mapkey import data.map.strict (map) import qualified data.map.strict map class mapkey k type mmap k v = r | r -> k v type mmap k v = map k v empty :: mmap k v default empty :: (mmap k v ~ map k v) => mmap k v empty = map.empty insert :: k -> v -> mmap k v -> mmap k v default insert :: (mmap k v ~ map k v, ord k) => k -> v -> mmap k v -> mmap k v insert = map.insert lookuple :: k -> mmap k v -> [(k, v)] default lookuple :: (mmap k v ~ map k v, ord k) => k -> mmap k v -> [(k, v)] lookuple k m = case map.lookuple k m of nothing -> [] e -> [e] instance mapkey () type mmap () v = maybe v empty = nothing insert _ v _ = v lookuple _ m = case m of nothing -> [] (just v) -> [((), v)] this means client code still has define boilerplate orphan instances like
instance mapkey int i'd rather see solution uses overlapping instances instead.
Comments
Post a Comment