changeset-containers (empty) → 0.1.0.0
raw patch · 14 files changed
+456/−0 lines, 14 filesdep +basedep +changesetdep +changeset-containers
Dependencies added: base, changeset, changeset-containers, containers, falsify, monoid-extras, tasty, tasty-hunit
Files
- CHANGELOG.md +5/−0
- LICENSE +20/−0
- changeset-containers.cabal +93/−0
- src/Data/Monoid/RightAction/IntMap.hs +20/−0
- src/Data/Monoid/RightAction/IntSet.hs +17/−0
- src/Data/Monoid/RightAction/Map.hs +20/−0
- src/Data/Monoid/RightAction/Sequence.hs +29/−0
- src/Data/Monoid/RightAction/Set.hs +17/−0
- test/IntMap.hs +41/−0
- test/IntSet.hs +41/−0
- test/Main.hs +26/−0
- test/Map.hs +41/−0
- test/Sequence.hs +45/−0
- test/Set.hs +41/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for changeset++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2023 Manuel Bärenz++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ changeset-containers.cabal view
@@ -0,0 +1,93 @@+cabal-version: 3.0+name: changeset-containers+-- PVP summary: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 0.1.0.0+synopsis: Stateful monad transformer based on monoidal actions+description:+ A general state monad transformer with separate types for the state and the possible changes.+ It can be defined for any monoid action.+ The monoid represents "changes", "updates", "edits" or "diffs" on the state.+ This package exposes typical changes for @containers@ such as maps, sequences, and sets.+ To change individual elements of a container, have a look at the indexed changes in [@changeset-lens@](hackage.haskell.org/package/changeset-lens).++license: MIT+license-file: LICENSE+author: Manuel Bärenz+maintainer: programming@manuelbaerenz.de+copyright: MIT+category: Control+build-type: Simple+extra-doc-files: CHANGELOG.md++source-repository head+ type: git+ location: https://github.com/turion/changeset++flag dev+ description: Enable warnings as errors. Active on ci.+ default: False+ manual: True++common opts+ ghc-options:+ -Wall++ if flag(dev)+ ghc-options:+ -Werror+ default-extensions:+ BangPatterns+ DeriveFunctor+ FlexibleInstances+ FunctionalDependencies+ GADTs+ KindSignatures+ MultiParamTypeClasses+ NamedFieldPuns+ RankNTypes+ ScopedTypeVariables+ TupleSections+ TypeOperators++library+ import: opts+ exposed-modules:+ Data.Monoid.RightAction.IntMap+ Data.Monoid.RightAction.IntSet+ Data.Monoid.RightAction.Map+ Data.Monoid.RightAction.Sequence+ Data.Monoid.RightAction.Set++ build-depends:+ base >=4.12 && <4.22,+ changeset ==0.1.0.0,+ containers >=0.6 && <0.8,+ monoid-extras ^>=0.6,++ hs-source-dirs: src+ default-language: Haskell2010++test-suite changeset-containers-test+ import: opts+ default-language: Haskell2010+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Main.hs+ build-depends:+ base,+ changeset,+ changeset-containers,+ containers,+ falsify ^>=0.2,+ monoid-extras,+ tasty ^>=1.4.2,+ tasty-hunit ^>=0.10.2,++ other-modules:+ IntMap+ IntSet+ Map+ Sequence+ Set
+ src/Data/Monoid/RightAction/IntMap.hs view
@@ -0,0 +1,20 @@+module Data.Monoid.RightAction.IntMap where++-- containers+import Data.IntMap++-- changeset+import Data.Monoid.RightAction (RightAction (..))++{- | Insert or delete an element in an 'IntMap'.++To change an element in an 'IntMap', see the indexed changes in [@changeset-lens@](hackage.haskell.org/package/changeset-lens).+-}+data IntMapChange a+ = Insert Int a+ | Delete Int+ deriving (Show, Read, Eq, Ord, Functor)++instance RightAction (IntMapChange a) (IntMap a) where+ actRight m (Insert k a) = insert k a m+ actRight m (Delete k) = delete k m
+ src/Data/Monoid/RightAction/IntSet.hs view
@@ -0,0 +1,17 @@+module Data.Monoid.RightAction.IntSet where++-- containers+import Data.IntSet++-- changeset+import Data.Monoid.RightAction (RightAction (..))++-- | Insert or delete an element in an 'IntSet'.+data IntSetChange+ = Insert Int+ | Delete Int+ deriving (Show, Read, Eq, Ord)++instance RightAction IntSetChange IntSet where+ actRight s (Insert k) = insert k s+ actRight s (Delete k) = delete k s
+ src/Data/Monoid/RightAction/Map.hs view
@@ -0,0 +1,20 @@+module Data.Monoid.RightAction.Map where++-- containers+import Data.Map++-- changeset+import Data.Monoid.RightAction (RightAction (..))++{- | Insert or delete an element in a 'Map'.++To change an element in an 'Map', see the indexed changes in [@changeset-lens@](hackage.haskell.org/package/changeset-lens).+-}+data MapChange k a+ = Insert k a+ | Delete k+ deriving (Show, Read, Eq, Ord, Functor)++instance (Ord k) => RightAction (MapChange k a) (Map k a) where+ actRight m (Insert k a) = insert k a m+ actRight m (Delete k) = delete k m
+ src/Data/Monoid/RightAction/Sequence.hs view
@@ -0,0 +1,29 @@+module Data.Monoid.RightAction.Sequence where++import Data.Monoid.RightAction (RightAction (..))+import Data.Sequence++{- | Insert or delete an element at either end of a 'Seq'.++To change an element in a 'Seq', see the indexed changes in [@changeset-lens@](hackage.haskell.org/package/changeset-lens).+-}+data SeqChange a+ = -- | Prepend an element+ Cons a+ | -- | Append an element+ Snoc a+ | -- | Drop an element from the left+ Uncons+ | -- | Drop an element from the right+ Unsnoc+ deriving (Show, Read, Eq, Ord, Functor)++instance RightAction (SeqChange a) (Seq a) where+ actRight s (Cons a) = a <| s+ actRight s (Snoc a) = s |> a+ actRight s Uncons = case viewl s of+ EmptyL -> empty+ _ :< as' -> as'+ actRight s Unsnoc = case viewr s of+ EmptyR -> empty+ as' :> _ -> as'
+ src/Data/Monoid/RightAction/Set.hs view
@@ -0,0 +1,17 @@+module Data.Monoid.RightAction.Set where++-- containers+import Data.Set++-- changeset+import Data.Monoid.RightAction (RightAction (..))++-- | Insert or delete an element in a 'Set'.+data SetChange k+ = Insert k+ | Delete k+ deriving (Show, Read, Eq, Ord)++instance (Ord k) => RightAction (SetChange k) (Set k) where+ actRight s (Insert k) = insert k s+ actRight s (Delete k) = delete k s
+ test/IntMap.hs view
@@ -0,0 +1,41 @@+module IntMap where++-- base+import Prelude hiding (Foldable (..))++-- containers+import Data.IntMap.Strict (singleton)++-- tasty+import Test.Tasty++-- tasty-hunit+import Test.Tasty.HUnit (testCase, (@?=))++-- changeset+import Control.Monad.Changeset.Class+import Control.Monad.Trans.Changeset++-- changeset-containers+import Data.Monoid.RightAction.IntMap++tests :: TestTree+tests =+ testGroup+ "IntMap"+ [ testCase "Can insert" $+ runChangeset (changeSingle (Insert 0 True :: IntMapChange Bool)) mempty @?= ((), singleton 0 True)+ , testCase "Can read after insert" $+ let action = do+ changeSingle (Insert 0 True :: IntMapChange Bool)+ m <- current+ changeSingle $ Insert 0 False+ return m+ in runChangeset action mempty @?= (singleton 0 True, singleton 0 False)+ , testCase "Can delete after insert" $+ let action = do+ changeSingle (Insert 0 True :: IntMapChange Bool)+ changeSingle $ Insert 1 False+ changeSingle $ Delete 0+ in execChangeset action mempty @?= singleton 1 False+ ]
+ test/IntSet.hs view
@@ -0,0 +1,41 @@+module IntSet where++-- base+import Prelude hiding (Foldable (..))++-- containers+import Data.IntSet (fromList, singleton)++-- tasty+import Test.Tasty++-- tasty-hunit+import Test.Tasty.HUnit (testCase, (@?=))++-- changeset+import Control.Monad.Changeset.Class+import Control.Monad.Trans.Changeset++-- changeset-containers+import Data.Monoid.RightAction.IntSet++tests :: TestTree+tests =+ testGroup+ "IntSet"+ [ testCase "Can insert" $+ runChangeset (changeSingle (Insert 0)) mempty @?= ((), singleton 0)+ , testCase "Can read after insert" $+ let action = do+ changeSingle $ Insert 0+ m <- current+ changeSingle $ Insert 1+ return m+ in runChangeset action mempty @?= (singleton 0, fromList [0, 1])+ , testCase "Can delete after insert" $+ let action = do+ changeSingle $ Insert 0+ changeSingle $ Insert 1+ changeSingle $ Delete 0+ in execChangeset action mempty @?= singleton 1+ ]
+ test/Main.hs view
@@ -0,0 +1,26 @@+module Main (main) where++-- base+import Prelude hiding (Foldable (..))++-- tasty+import Test.Tasty++-- changeset-containers-test+import qualified IntMap+import qualified IntSet+import qualified Map+import qualified Sequence+import qualified Set++main :: IO ()+main =+ defaultMain $+ testGroup+ "changeset-containers"+ [ IntMap.tests+ , Map.tests+ , IntSet.tests+ , Set.tests+ , Sequence.tests+ ]
+ test/Map.hs view
@@ -0,0 +1,41 @@+module Map where++-- base+import Prelude hiding (Foldable (..))++-- containers+import Data.Map.Strict (singleton)++-- tasty+import Test.Tasty++-- tasty-hunit+import Test.Tasty.HUnit (testCase, (@?=))++-- changeset+import Control.Monad.Changeset.Class+import Control.Monad.Trans.Changeset++-- changeset-containers+import Data.Monoid.RightAction.Map++tests :: TestTree+tests =+ testGroup+ "Map"+ [ testCase "Can insert" $+ runChangeset (changeSingle (Insert "0" True :: MapChange String Bool)) mempty @?= ((), singleton "0" True)+ , testCase "Can read after insert" $+ let action = do+ changeSingle (Insert "0" True :: MapChange String Bool)+ m <- current+ changeSingle $ Insert "0" False+ return m+ in runChangeset action mempty @?= (singleton "0" True, singleton "0" False)+ , testCase "Can delete after insert" $+ let action = do+ changeSingle (Insert "0" True :: MapChange String Bool)+ changeSingle $ Insert "1" False+ changeSingle $ Delete "0"+ in execChangeset action mempty @?= singleton "1" False+ ]
+ test/Sequence.hs view
@@ -0,0 +1,45 @@+module Sequence where++-- base+import Prelude hiding (Foldable (..))++-- containers+import Data.Sequence (fromList, singleton)++-- tasty+import Test.Tasty++-- tasty-hunit+import Test.Tasty.HUnit (testCase, (@?=))++-- changeset+import Control.Monad.Changeset.Class+import Control.Monad.Trans.Changeset (changeSingle, execChangeset, runChangeset)++-- changeset-containers+import Data.Monoid.RightAction.Sequence++tests :: TestTree+tests =+ testGroup+ "Map"+ [ testCase "Can insert" $+ runChangeset (changeSingle (Cons 0 :: SeqChange Int)) mempty @?= ((), singleton (0 :: Int))+ , testCase "Can read after insert" $+ let action = do+ changeSingle (Cons 1 :: SeqChange Int)+ m <- current+ changeSingle $ Cons 0+ return m+ in runChangeset action mempty @?= (singleton (1 :: Int), fromList [0, 1])+ , testCase "Can delete after insert" $+ let action = do+ changeSingle (Cons 1 :: SeqChange Int)+ m <- current+ changeSingle $ Cons 0+ changeSingle $ Snoc 3+ changeSingle $ Snoc 99+ changeSingle Unsnoc+ return m+ in execChangeset action (singleton (2 :: Int)) @?= fromList [0, 1, 2, 3]+ ]
+ test/Set.hs view
@@ -0,0 +1,41 @@+module Set where++-- base+import Prelude hiding (Foldable (..))++-- containers+import Data.Set (fromList, singleton)++-- tasty+import Test.Tasty++-- tasty-hunit+import Test.Tasty.HUnit (testCase, (@?=))++-- changeset+import Control.Monad.Changeset.Class+import Control.Monad.Trans.Changeset++-- changeset-containers+import Data.Monoid.RightAction.Set++tests :: TestTree+tests =+ testGroup+ "Set"+ [ testCase "Can insert" $+ runChangeset (changeSingle (Insert True)) mempty @?= ((), singleton True)+ , testCase "Can read after insert" $+ let action = do+ changeSingle $ Insert True+ m <- current+ changeSingle $ Insert False+ return m+ in runChangeset action mempty @?= (singleton True, fromList [True, False])+ , testCase "Can delete after insert" $+ let action = do+ changeSingle $ Insert True+ changeSingle $ Insert False+ changeSingle $ Delete True+ in execChangeset action mempty @?= singleton False+ ]