packages feed

queuelike-1.0.7: Data/Queue/Fuse/Map.hs

{-# LANGUAGE TypeFamilies, PatternGuards #-}
module Data.Queue.Fuse.Map where

import Data.Semigroup
import Data.Queue.Class
import Data.Map
import qualified Data.Map as Map

newtype FuseMapQ k v = FMQ (Map k v) deriving (Show)

instance (Ord k, Semigroup v) => IQueue (FuseMapQ k v) where
	type QueueKey (FuseMapQ k v) = (k, v)
	empty = FMQ Map.empty
	singleton = FMQ . uncurry Map.singleton
	fromList = FMQ . Map.fromListWith sappend

	null (FMQ m) = Map.null m
	size (FMQ m) = Map.size m
	extract (FMQ m) = fmap (fmap FMQ) (Map.minViewWithKey m)
	FMQ m1 `merge` FMQ m2 = FMQ (Map.unionWith sappend m1 m2)
	mergeAll qs = FMQ (Map.unionsWith sappend [m | FMQ m <- qs])
	(k, v) `insert` FMQ m = FMQ (Map.insertWith sappend k v m)

extractSingle :: (Ord k, Semigroup v) => FuseMapQ k v -> Maybe (k, v)
extractSingle (FMQ m)
	| Map.size m == 1, (k, v) <- findMin m
		= Just (k, v)
extractSingle _ = Nothing

replace :: (Ord k, Semigroup v) => v -> FuseMapQ k v -> FuseMapQ k v
replace v (FMQ m) = FMQ (updateMin (\ _ -> Just v) m)