packages feed

appendmap (empty) → 0.1.1

raw patch · 7 files changed

+179/−0 lines, 7 filesdep +appendmapdep +basedep +containerssetup-changed

Dependencies added: appendmap, base, containers, hspec

Files

+ ChangeLog.md view
@@ -0,0 +1,7 @@+# Changelog for appendmap++## Unreleased changes++## 0.1.1++* Initial release on Hackage.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Alexey Kotlyarov (c) 2018++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 Alexey Kotlyarov 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,46 @@+# appendmap++[![Build status](https://img.shields.io/travis/koterpillar/appendmap.svg)](https://travis-ci.org/koterpillar/appendmap)+[![Hackage](https://img.shields.io/hackage/v/appendmap.svg)](https://hackage.haskell.org/package/appendmap)+[![Stackage LTS](https://www.stackage.org/package/appendmap/badge/lts)](https://www.stackage.org/lts/package/appendmap)+[![Hackage dependencies](https://img.shields.io/hackage-deps/v/appendmap.svg)](https://packdeps.haskellers.com/feed?needle=appendmap)++A `Data.Map` wrapper with a `Semigroup` and `Monoid` instances that delegate to+the individual keys.++```haskell+import qualified Data.Map as Map+import Data.Map.Append++> one = AppendMap $ Map.fromList [(1, "hello"), (2, "goodbye")]+> two = AppendMap $ Map.fromList [(1, "world"), (3, "again")]++> unAppendMap (one <> two)+fromList [(1, "helloworld"), (2, "goodbye"), (3, "again")]+```++## Motivation++`Data.Map` has a `Semigroup` instance that keeps the values from the first+argument in case of a key conflict:++```haskell+import qualified Data.Map as Map+import Data.Map.Append++> Map.fromList [(1, "hello")] <> Map.fromList [(1, "goodbye")]+fromList [(1, "hello")]+```++A different instance has been suggested for a long time+([1](https://mail.haskell.org/pipermail/libraries/2012-April/017743.html),+[2](https://ghc.haskell.org/trac/ghc/ticket/1460)), but this is a breaking change and hasn't happened yet (as of 2018-08).++## Development++Source code is formatted with `hindent` _then_ `stylish-haskell`.++### Releasing++* Run `./bumpversion patch|minor|major`. This will create a new version and push+  it to the repository to be released.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ appendmap.cabal view
@@ -0,0 +1,54 @@+-- This file has been generated from package.yaml by hpack version 0.28.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: a323dd29d1810894fafc021571b49e8c3ca23a22516736fe70ec955cec2be6e4++name:           appendmap+version:        0.1.1+synopsis:       Map with a Semigroup and Monoid instances delegating to Semigroup of the elements+description:    Please see the README on GitHub at <https://github.com/koterpillar/appendmap#readme>+category:       Data Structures+homepage:       https://github.com/koterpillar/appendmap#readme+bug-reports:    https://github.com/koterpillar/appendmap/issues+author:         Alexey Kotlyarov+maintainer:     a@koterpillar.com+copyright:      2018 Alexey Kotlyarov+license:        BSD3+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.10+extra-source-files:+    ChangeLog.md+    README.md++source-repository head+  type: git+  location: https://github.com/koterpillar/appendmap++library+  exposed-modules:+      Data.Map.Append+  other-modules:+      Paths_appendmap+  hs-source-dirs:+      src+  build-depends:+      base >=4.7 && <5+    , containers+  default-language: Haskell2010++test-suite appendmap-test+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  other-modules:+      Paths_appendmap+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      appendmap+    , base >=4.7 && <5+    , containers+    , hspec+  default-language: Haskell2010
+ src/Data/Map/Append.hs view
@@ -0,0 +1,22 @@+module Data.Map.Append where++import           Data.Map           (Map)+import qualified Data.Map           as Map++import           Data.Monoid        hiding ((<>))+import           Data.Semigroup++import qualified Data.List.NonEmpty as NE++newtype AppendMap k v = AppendMap+  { unAppendMap :: Map k v+  }++instance (Ord k, Semigroup v) => Semigroup (AppendMap k v) where+  AppendMap a <> AppendMap b = AppendMap $ Map.unionWith (<>) a b+  sconcat = AppendMap . Map.unionsWith (<>) . NE.toList . fmap unAppendMap++instance (Ord k, Semigroup v) => Monoid (AppendMap k v) where+  mempty = AppendMap Map.empty+  mappend = (<>)+  mconcat = AppendMap . Map.unionsWith (<>) . fmap unAppendMap
+ test/Spec.hs view
@@ -0,0 +1,18 @@+import qualified Data.Map        as Map+import           Data.Map.Append++import           Data.Semigroup++import           Test.Hspec++main :: IO ()+main =+  hspec $+  describe "AppendMap" $ do+    it "has empty element" $+      unAppendMap (mempty :: AppendMap Int String) `shouldBe` Map.empty+    it "combines elements" $ do+      let one = AppendMap $ Map.fromList [(1, "hello"), (2, "goodbye")]+      let two = AppendMap $ Map.fromList [(1, "world"), (3, "again")]+      unAppendMap (one <> two) `shouldBe`+        Map.fromList [(1, "helloworld"), (2, "goodbye"), (3, "again")]