packages feed

bookkeeper 0.1.0.0 → 0.1.1.0

raw patch · 5 files changed

+52/−21 lines, 5 files

Files

bookkeeper.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           bookkeeper-version:        0.1.0.0+version:        0.1.1.0 description:    Please see README.md homepage:       http://github.com/turingjump/bookkeeper#readme bug-reports:    https://github.com/turingjump/bookkeeper/issues
src/Bookkeeper.hs view
@@ -8,12 +8,17 @@ -- >>> let julian :: Person = emptyBook & #age =: 28 & #name =: "Julian K. Arni" -- -- The OverloadedLabels and TypeOperators extensions are also required.+--+-- A word of warning: The signatures for most of the functions are quite+-- arcane, even though their behaviour is intuitive.    -- * Initialization    emptyBook+   -- * Getters   , (?:)   , get+   -- * Setters   , set   , (=:)@@ -21,6 +26,9 @@   -- * Modifying   , modify   , (%:)++  -- * Deleting+  , delete    -- * Types   , Book
src/Bookkeeper/Internal.hs view
@@ -66,6 +66,7 @@ (?:) :: forall field book val. (Map.Submap '[field :=> val] book, Contains book field val )   => Book' book -> Key field -> val (?:) = flip get+infixl 3 ?:  -- | Sets or updates a field to a value. --@@ -104,6 +105,7 @@   )   => Key field -> val -> Book' old -> Book' new (=:) = set+infix 3 =:   -- | Apply a function to a field.@@ -151,6 +153,24 @@   , Map.AsMap new ~ new   ) =>  Key field -> (val -> val') -> Book' old -> Book new (%:) = modify+infixr 3 %:+++-- | Delete a field from a 'Book', if it exists. If it does not, returns the+-- @Book@ unmodified.+--+-- >>> get #name $ delete #name julian+-- ...+-- ...  • The provided Book does not contain the field "name"+-- ...    Book type:+-- ...    '["age" ':-> Int]+-- ...  • In the expression: get #name+-- ...+delete :: forall field old .+        ( Map.Submap (Map.AsMap (old Map.:\ field)) old+        ) => Key field -> Book' old -> Book (old Map.:\ field)+delete _ (Book bk) = Book $ Map.submap bk+   -- * Mapping
test/BookkeeperSpec.hs view
@@ -7,12 +7,12 @@  spec :: Spec spec = describe "books" $ do+    let p :: Person+           = emptyBook+           & #name =: "Julian K. Arni"+           & #age =: 28      it "allows creation" $ do-      let _p :: Person-             = emptyBook-             & #name =: "Julian K. Arni"-             & #age  =:  28       typeLevelTest      it "allows creation out of order" $ do@@ -23,29 +23,29 @@       typeLevelTest      it "allows access" $ do-      let p :: Person-             = emptyBook-             & #name =: "Julian K. Arni"-             & #age  =:  28       get #name p  `shouldBe` "Julian K. Arni"      it "allows update" $ do-      let p :: Person-             = emptyBook-             & #name =: "Julian K. Arni"-             & #age =: 28-             & #name %: fmap toUpper-      get #name p `shouldBe` "JULIAN K. ARNI"+      let p' :: Person+             = p & #name %: fmap toUpper+      get #name p' `shouldBe` "JULIAN K. ARNI"      it "allows extension" $ do-      let p :: Person-             = emptyBook-             & #name =: "Julian K. Arni"-             & #age =: 28       let p' = #email =: "jkarni<at>turingjump<dot>com" $ p       get #email p' `shouldBe` ("jkarni<at>turingjump<dot>com" :: String) +    it "allows deleting" $ do+      let _p = delete #name p+      typeLevelTest++    it "allows nested updates" $ do+      let timeTravelingJulian = p & #child =: p+          p' = timeTravelingJulian & #child %: #name %: fmap toUpper+      p' ?: #name `shouldBe` "Julian K. Arni"+      p' ?: #child ?: #name `shouldBe` "JULIAN K. ARNI"+ type Person = Book '[ "name" :=> String , "age" :=> Int]+  typeLevelTest :: Expectation typeLevelTest = True `shouldBe` True
test/Readme.lhs view
@@ -18,6 +18,9 @@ -- "Jane" ~~~ +It bears some similarities to Nikita Volkov's [record](https://nikita-volkov.github.io/record/)+library, but requires no Template Haskell.+ Accesing a field that does not exist is a type error, made nicer with GHCs new custom type errors: @@ -32,10 +35,10 @@ The order in which fields are inserted or appear in types does not matter. That is, in: -~~ {.haskell ignore}+~~~ {.haskell} -- type A = Book '[ "field1" :=> Int, "field2" :=> Bool] -- type B = Book '[ "field2" :=> Bool "field1" :=> Int ]-~~+~~~  Types `A` and `B` are the same.