packages feed

monoid-map (empty) → 0.1.0.0

raw patch · 5 files changed

+131/−0 lines, 5 filesdep +appendmapdep +basedep +monoidal-containers

Dependencies added: appendmap, base, monoidal-containers, reflex, witherable

Files

+ CHANGELOG.md view
@@ -0,0 +1,4 @@+# Revision history for monoid-map++## 2021-11-17+* Added the code for Data.MonoidMap.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2021, Obsidian Systems LLC++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Obsidian Systems LLC nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,5 @@+# monoid-map+[![Haskell](https://img.shields.io/badge/language-Haskell-orange.svg)](https://haskell.org) [![Hackage](https://img.shields.io/hackage/v/monoid-map.svg)](https://hackage.haskell.org/package/monoid-map) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/monoid-map/badge)](https://matrix.hackage.haskell.org/#/package/monoid-map) [![Github CI](https://github.com/obsidiansystems/monoid-map/workflows/Haskell%20CI/badge.svg)](https://github.com/obsidiansystems/monoid-map/actions) [![BSD3 License](https://img.shields.io/badge/license-BSD3-blue.svg)](https://github.com/obsidiansystems/monoid-map/blob/master/LICENSE)+++Newtype wrapper around 'Data.Map.Monoidal.MonoidalMap' that has a correct 'Group' instance.
+ monoid-map.cabal view
@@ -0,0 +1,37 @@+cabal-version:      2.4+name:               monoid-map+version:            0.1.0.0+synopsis:           Newtype wrapper around 'Data.Map.Monoidal.MonoidalMap' that has a correct 'Group' instance.+description:+  The 'Group' instance for Data.MonoidMap has a unique neutral element,+  as compared to 'Data.Map.Monoidal.MonoidalMap'.++homepage:           https://github.com/obsidiansystems/monoid-map+bug-reports:+  https://github.com/obsidiansystems/monoid-map/issues++license:            BSD-3-Clause+license-file:       LICENSE+author:             Obsidian Systems LLC+maintainer:         maintainer@obsidian.systems+copyright:          (c) 2021 Obsidian Systems LLC+category:           Data+extra-source-files: CHANGELOG.md README.md++library+  exposed-modules:  Data.MonoidMap+  other-extensions:+    DeriveTraversable+    FlexibleContexts+    GeneralizedNewtypeDeriving+    TypeFamilies+    UndecidableInstances++  build-depends:+      appendmap+    , base >= 4 && < 5+    , monoidal-containers+    , reflex+    , witherable+  hs-source-dirs:   src+  default-language: Haskell2010
+ src/Data/MonoidMap.hs view
@@ -0,0 +1,55 @@+-- | This module contains a newtype wrapper around 'Data.Map.Map' that has a+-- correct 'Group' instance compared to the one for+-- 'Data.Map.Monoidal.MonoidalMap', in that it has a unique neutral element.+-- This comes with different constraints on the parameters (check the instances+-- for 'Semigroup' and 'Monoid' of the corresponding data structures if you're+-- interested).+--+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE UndecidableInstances #-} -- For (Eq (QueryResult q), Ord k, Query q) => Query (MonoidMap k q)+{-# LANGUAGE StandaloneDeriving #-}+module Data.MonoidMap where++import Data.Witherable+import Data.AppendMap+import Data.Map.Monoidal (MonoidalMap)+import Data.Map.Monoidal as Map+import Data.Semigroup (Semigroup, (<>))+import Reflex (Query, QueryResult, crop, Group(..), Additive)++-- | Newtype wrapper around Data.Map.Monoidal.MonoidalMap+newtype MonoidMap k v = MonoidMap { unMonoidMap :: MonoidalMap k v }+  deriving (Show, Eq, Ord, Foldable, Functor, Traversable)++deriving instance Filterable (MonoidalMap k) => Filterable (MonoidMap k)++-- | Convert a MonoidalMap into a MonoidMap+monoidMap :: (Ord k, Eq v, Monoid v) => MonoidalMap k v -> MonoidMap k v+monoidMap = MonoidMap . Map.filter (/= mempty)++instance (Eq (QueryResult q), Ord k, Query q) => Query (MonoidMap k q) where+  type QueryResult (MonoidMap k q) = MonoidMap k (QueryResult q)+  crop (MonoidMap q) (MonoidMap qr) =+    -- This assumes that the query result of a null query should be null+    monoidMap $ Map.intersectionWith crop q qr++instance (Monoid a, Eq a, Ord k) => Semigroup (MonoidMap k a) where+  MonoidMap a <> MonoidMap b =+    let combine _ a' b' =+          let c = a' `mappend` b'+          in if c == mempty+               then Nothing+               else Just c+    in MonoidMap $ Map.mergeWithKey combine id id a b++instance (Ord k, Monoid a, Eq a) => Monoid (MonoidMap k a) where+  mempty = MonoidMap Map.empty+  mappend = (<>)++instance (Ord k, Monoid a, Eq a, Group a) => Group (MonoidMap k a) where+  negateG = fmap negateG++instance (Ord k, Monoid a, Eq a, Group a, Additive a) => Additive (MonoidMap k a)