Open
Description
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.