Skip to content

Add more conversions between HashSet and HashMap #349

Open
@josephcsible

Description

@josephcsible

Rough sketch:

{-# LANGUAGE CPP #-}

import Data.Semigroup (Arg(..))
import qualified Data.HashMap.Internal.Array as A
import Data.HashMap.Internal
import Data.HashSet.Internal

#if MIN_VERSION_hashable(1,3,0)
fromArgSet :: HashSet (Arg k a) -> HashMap k a
fromArgSet = go . toMap
  where
    go Empty = Empty
    go (Leaf h (L (Arg k v) _)) = Leaf h (L k v)
    go (BitmapIndexed b ary) = BitmapIndexed b $ A.map go ary
    go (Full ary) = Full $ A.map go ary
    go (Collision h ary) = Collision h $
                           A.map' (\ (L (Arg k v) _) -> L k v) ary
{-# INLINE fromArgSet #-}

argSet :: HashMap k a -> HashSet (Arg k a)
argSet = fromMap . go
  where
    go Empty = Empty
    go (Leaf h (L k v)) = Leaf h (L (Arg k v) ())
    go (BitmapIndexed b ary) = BitmapIndexed b $ A.map go ary
    go (Full ary) = Full $ A.map go ary
    go (Collision h ary) = Collision h $
                           A.map' (\ (L k v) -> L (Arg k v) ()) ary
{-# INLINE argSet #-}
#endif

These are safe since Arg x y and x have the same hash (in hashable 1.3.0.0 and up, hence the #if). See also haskell/containers#814.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions