packages feed

composite-base 0.7.5.0 → 0.7.6.0

raw patch · 4 files changed

+186/−33 lines, 4 filesdep ~basedep ~lensdep ~profunctorsPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base, lens, profunctors, template-haskell, vinyl

API changes (from Hackage documentation)

+ Composite.Record: rlensCo :: (Functor f, Functor g, RElem (s :-> a) rs) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)
+ Composite.Record: rlensContra :: (Contravariant f, Functor g, RElem (s :-> a) rs) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)
- Composite.Record: infixr 5 :^:
+ Composite.Record: infixr 5 :!:
- Composite.Record: pattern (:^:) :: Functor f => () => f a -> Rec f rs -> Rec f ((s :-> a) : rs)
+ Composite.Record: pattern (:!:) :: Contravariant f => () => f a -> Rec f rs -> Rec f ((s :-> a) : rs)
- Composite.Record: rlens' :: (Functor f, Functor g, RElem (s :-> a) rs, Functor g) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)
+ Composite.Record: rlens' :: (Functor f, Functor g, RElem (s :-> a) rs) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)

Files

composite-base.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.34.3.+-- This file has been generated from package.yaml by hpack version 0.34.5. -- -- see: https://github.com/sol/hpack ----- hash: 42cd7a9297580ad2d6a569e06f0a035a2d63a52e1725a2680e8b062db07f8910+-- hash: 1bd1f66bd3d38d9ed108f5b7c2e4d437903998f82224fddeefae706b03de417d  name:           composite-base-version:        0.7.5.0+version:        0.7.6.0 synopsis:       Shared utilities for composite-* packages. description:    Shared helpers for the various composite packages. category:       Records@@ -29,22 +29,45 @@       Paths_composite_base   hs-source-dirs:       src-  default-extensions: ConstraintKinds DataKinds FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving MultiParamTypeClasses NamedFieldPuns OverloadedStrings PatternSynonyms PolyKinds RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving StrictData TemplateHaskell TupleSections TypeApplications TypeFamilies TypeOperators ViewPatterns+  default-extensions:+      ConstraintKinds+      DataKinds+      FlexibleContexts+      FlexibleInstances+      FunctionalDependencies+      GADTs+      GeneralizedNewtypeDeriving+      MultiParamTypeClasses+      NamedFieldPuns+      OverloadedStrings+      PatternSynonyms+      PolyKinds+      RankNTypes+      RecordWildCards+      ScopedTypeVariables+      StandaloneDeriving+      StrictData+      TemplateHaskell+      TupleSections+      TypeApplications+      TypeFamilies+      TypeOperators+      ViewPatterns   ghc-options: -Wall -O2   build-depends:-      base >=4.7 && <5-    , deepseq >=1.4 && <1.5+      base >=4.12 && <5+    , deepseq ==1.4.*     , exceptions >=0.8.3 && <0.11-    , lens >=4.15.4 && <5.1+    , lens >=4.15.4 && <5.2     , monad-control >=1.0.2.2 && <1.1     , mtl >=2.2.1 && <2.3-    , profunctors >=5.2.1 && <5.6-    , template-haskell >=2.11.1.0 && <2.17+    , profunctors >=5.2.1 && <5.7+    , template-haskell >=2.11.1.0 && <2.19     , text >=1.2.2.2 && <1.3     , transformers >=0.5.2.0 && <0.6     , transformers-base >=0.4.4 && <0.5     , unliftio-core >=0.1.0.0 && <0.3.0.0-    , vinyl >=0.5.3 && <0.14+    , vinyl >=0.5.3 && <0.15   default-language: Haskell2010  test-suite composite-base-test@@ -56,23 +79,46 @@       Paths_composite_base   hs-source-dirs:       test-  default-extensions: ConstraintKinds DataKinds FlexibleContexts FlexibleInstances FunctionalDependencies GADTs GeneralizedNewtypeDeriving MultiParamTypeClasses NamedFieldPuns OverloadedStrings PatternSynonyms PolyKinds RankNTypes RecordWildCards ScopedTypeVariables StandaloneDeriving StrictData TemplateHaskell TupleSections TypeApplications TypeFamilies TypeOperators ViewPatterns+  default-extensions:+      ConstraintKinds+      DataKinds+      FlexibleContexts+      FlexibleInstances+      FunctionalDependencies+      GADTs+      GeneralizedNewtypeDeriving+      MultiParamTypeClasses+      NamedFieldPuns+      OverloadedStrings+      PatternSynonyms+      PolyKinds+      RankNTypes+      RecordWildCards+      ScopedTypeVariables+      StandaloneDeriving+      StrictData+      TemplateHaskell+      TupleSections+      TypeApplications+      TypeFamilies+      TypeOperators+      ViewPatterns   ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N -fno-warn-orphans   build-depends:       QuickCheck-    , base >=4.7 && <5+    , base >=4.12 && <5     , composite-base-    , deepseq >=1.4 && <1.5+    , deepseq ==1.4.*     , exceptions >=0.8.3 && <0.11     , hspec-    , lens >=4.15.4 && <5.1+    , lens >=4.15.4 && <5.2     , monad-control >=1.0.2.2 && <1.1     , mtl >=2.2.1 && <2.3-    , profunctors >=5.2.1 && <5.6-    , template-haskell >=2.11.1.0 && <2.17+    , profunctors >=5.2.1 && <5.7+    , template-haskell >=2.11.1.0 && <2.19     , text >=1.2.2.2 && <1.3     , transformers >=0.5.2.0 && <0.6     , transformers-base >=0.4.4 && <0.5     , unliftio-core >=0.1.0.0 && <0.3.0.0-    , vinyl >=0.5.3 && <0.14+    , vinyl >=0.5.3 && <0.15   default-language: Haskell2010
src/Composite/Record.hs view
@@ -2,9 +2,9 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} module Composite.Record   ( Rec((:&), RNil), Record-  , pattern (:*:), pattern (:^:)+  , pattern (:*:), pattern (:^:), pattern (:!:)   , (:->)(Val, getVal), _Val, val, valName, valWithName-  , RElem, rlens, rlens'+  , RElem, rlens, rlens', rlensCo, rlensContra   , AllHave, HasInstances, ValuesAllHave   , zipRecsWith, reifyDicts, reifyVal, recordToNonEmpty   , ReifyNames(reifyNames)@@ -16,6 +16,7 @@ import Control.Lens (Iso, iso) import Control.Lens.TH (makeWrapped) import Data.Functor.Identity (Identity(Identity))+import Data.Functor.Contravariant (Contravariant(contramap)) import Data.Kind (Constraint) import Data.List.NonEmpty (NonEmpty((:|))) import Data.Proxy (Proxy(Proxy))@@ -169,6 +170,11 @@   (:^:) fa rs = fmap Val fa :& rs infixr 5 :^: +pattern (:!:) :: Contravariant f => () => f a -> Rec f rs -> Rec f (s :-> a ': rs)+pattern (:!:) fa rs <- (contramap Val -> fa) :& rs where+  (:!:) fa rs = contramap getVal fa :& rs+infixr 5 :!:+ -- |Reify the type of a val. reifyVal :: proxy (s :-> a) -> (s :-> a) -> (s :-> a) reifyVal _ = id@@ -217,15 +223,47 @@ -- Then: -- -- @---   view (rlens' fBar_)                      rec == Just "hello!"---   set  (rlens' fBar_) Nothing              rec == Just 123 :^: Nothing       :^: Nil---   over (rlens' fBar_) (fmap (map toUpper)) rec == Just 123 :^: Just "HELLO!" :^: Nil+--   view (rlensCo fBar_)                      rec == Just "hello!"+--   set  (rlensCo fBar_) Nothing              rec == Just 123 :^: Nothing       :^: Nil+--   over (rlensCo fBar_) (fmap (map toUpper)) rec == Just 123 :^: Just "HELLO!" :^: Nil -- @-rlens' :: (Functor f, Functor g, RElem (s :-> a) rs, Functor g) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)-rlens' proxy f =+rlensCo :: (Functor f, Functor g, RElem (s :-> a) rs) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)+rlensCo proxy f =   Vinyl.rlens $ \ (fmap (getVal . reifyVal proxy) -> fa) ->     fmap Val <$> f fa+{-# INLINE rlensCo #-}++-- |Synonym for `rlensCo`+rlens' :: (Functor f, Functor g, RElem (s :-> a) rs) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)+rlens' = rlensCo {-# INLINE rlens' #-}++-- |Lens to a particular field of a record using a contravariant functor.+--+-- For example, given:+--+-- @+--   type FFoo = "foo" :-> Int+--   type FBar = "bar" :-> String+--   fBar_ :: Proxy FBar+--   fBar_ = Proxy+--+--   rec :: 'Rec' 'Predicate' '[FFoo, FBar]+--   rec = Predicate even :!: Predicate (even . length) :!: Nil+-- @+--+-- Then:+--+-- @+--   view (rlensContra fBar_)                           rec == Predicate even+--   set  (rlensContra fBar_) Predicate (odd . length)  rec == Predicate even :!: Predicate (odd . length) :!: Nil+--   over (rlensContra fBar_) (contramap show)          rec == Predicate even :!: Predicate (odd . length . show) :!: Nil+-- @+rlensContra :: (Contravariant f, Functor g, RElem (s :-> a) rs) => proxy (s :-> a) -> (f a -> g (f a)) -> Rec f rs -> g (Rec f rs)+rlensContra proxy f =+  Vinyl.rlens $ \(contramap (reifyVal proxy . Val) -> fa) ->+    contramap getVal <$> f fa+{-# INLINE rlensContra #-}  -- | 'zipWith' for Rec's. zipRecsWith :: (forall a. f a -> g a -> h a) -> Rec f as -> Rec g as -> Rec h as
src/Composite/TH.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} module Composite.TH   ( withProxies   , withLensesAndProxies@@ -18,6 +19,9 @@   ( Q, newName, mkName, nameBase   , Body(NormalB), cxt, Dec(PragmaD, SigD, ValD), Exp(VarE), Inline(Inlinable), Name, Pat(VarP), Phases(AllPhases), Pragma(InlineP), RuleMatch(FunLike)   , Type(AppT, ConT, ForallT, VarT), TyVarBndr(PlainTV, KindedTV), varT+#if MIN_VERSION_template_haskell(2,17,0)+  , Specificity(SpecifiedSpec)+#endif   ) import Language.Haskell.TH.Lens (_TySynD) @@ -141,31 +145,62 @@ withOpticsAndProxies :: Q [Dec] -> Q [Dec] withOpticsAndProxies = withBoilerplate True True +#if MIN_VERSION_template_haskell(2,17,0)+tyUnitToSpec :: Specificity -> TyVarBndr () -> TyVarBndr Specificity+tyUnitToSpec x (PlainTV n ()) = PlainTV n x+tyUnitToSpec x (KindedTV n () k) = KindedTV n x k++fieldDecUnitToSpec :: Specificity -> FieldDec () -> FieldDec Specificity+fieldDecUnitToSpec x (FieldDec n b t v) = FieldDec n (map (tyUnitToSpec x) b) t v++data FieldDec a = FieldDec+#else data FieldDec = FieldDec+#endif   { fieldName        :: Name+#if MIN_VERSION_template_haskell(2,17,0)+  , fieldBinders     :: [TyVarBndr a]+#else   , fieldBinders     :: [TyVarBndr]+#endif   , fieldTypeApplied :: Type   , fieldValueType   :: Type   }+ -- |TH splice which implements 'withLensesAndProxies', 'withPrismsAndProxies', and 'withOpticsAndProxies' withBoilerplate :: Bool -> Bool -> Q [Dec] -> Q [Dec] withBoilerplate generateLenses generatePrisms qDecs = do   decs <- qDecs    let fieldDecs = catMaybes . map fieldDecMay . toListOf (each . _TySynD) $ decs-+#if MIN_VERSION_template_haskell(2,17,0)+  let sFieldDecs = map (fieldDecUnitToSpec SpecifiedSpec) fieldDecs+#endif   proxyDecs <- traverse proxyDecFor fieldDecs-  lensDecs  <- if generateLenses then traverse lensDecFor  fieldDecs else pure []+#if MIN_VERSION_template_haskell(2,17,0)+  lensDecs  <- if generateLenses then traverse lensDecFor sFieldDecs else pure []+  prismDecs <- if generatePrisms then traverse prismDecFor sFieldDecs else pure []+#else +  lensDecs  <- if generateLenses then traverse lensDecFor fieldDecs else pure []   prismDecs <- if generatePrisms then traverse prismDecFor fieldDecs else pure []-+#endif   pure $ decs <> concat proxyDecs <> concat lensDecs <> concat prismDecs +#if MIN_VERSION_template_haskell(2,17,0)+fieldDecMay :: (Name, [TyVarBndr ()], Type) -> Maybe (FieldDec ())+#else fieldDecMay :: (Name, [TyVarBndr], Type) -> Maybe FieldDec+#endif fieldDecMay (fieldName, fieldBinders, ty) = case ty of   AppT (AppT (ConT n) _) fieldValueType | n == ''(:->) ->     let fieldTypeApplied         = foldl' AppT (ConT fieldName) (map binderTy fieldBinders)-        binderTy (PlainTV n')    = VarT n'+#if MIN_VERSION_template_haskell(2,17,0)+        binderTy (PlainTV n' _ )    = VarT n'+        binderTy (KindedTV n' _ _) = VarT n'+#else+        binderTy (PlainTV n' )    = VarT n'         binderTy (KindedTV n' _) = VarT n'+#endif     in Just $ FieldDec {..}   _ ->     Nothing@@ -175,7 +210,11 @@ prismNameFor = mkName . ("_" ++) . nameBase proxyNameFor = mkName . (++ "_") . over _head toLower . nameBase +#if MIN_VERSION_template_haskell(2,17,0)+proxyDecFor :: FieldDec () -> Q [Dec]+#else proxyDecFor :: FieldDec -> Q [Dec]+#endif proxyDecFor (FieldDec { fieldName, fieldTypeApplied }) = do   let proxyName = proxyNameFor fieldName @@ -187,7 +226,11 @@     , ValD (VarP proxyName) (NormalB proxyVal) []     ] +#if MIN_VERSION_template_haskell(2,17,0)+lensDecFor :: FieldDec Specificity -> Q [Dec]+#else lensDecFor :: FieldDec -> Q [Dec]+#endif lensDecFor (FieldDec {..}) = do   f  <- newName "f"   rs <- newName "rs"@@ -197,7 +240,11 @@       proxyName               = proxyNameFor fieldName       lensName                = lensNameFor fieldName       proxyVal                = VarE proxyName+#if MIN_VERSION_template_haskell(2,17,0)+      lensBinders             = fieldBinders ++ [PlainTV f SpecifiedSpec, PlainTV rs SpecifiedSpec]+#else       lensBinders             = fieldBinders ++ [PlainTV f, PlainTV rs]+#endif    lensContext <- cxt [ [t| Functor $fTy |], [t| $(pure fieldTypeApplied) ∈ $rsTy |] ]   lensType    <- [t| ($(pure fieldValueType) -> $fTy $(pure fieldValueType)) -> (Record $rsTy -> $fTy (Record $rsTy)) |]@@ -209,7 +256,11 @@     , ValD (VarP lensName) (NormalB rlensVal) []     ] +#if MIN_VERSION_template_haskell(2,17,0)+prismDecFor :: FieldDec Specificity -> Q [Dec]+#else prismDecFor :: FieldDec -> Q [Dec]+#endif prismDecFor (FieldDec {..}) = do   rs <- newName "rs" @@ -217,7 +268,11 @@       proxyName               = proxyNameFor fieldName       prismName               = prismNameFor fieldName       proxyVal                = VarE proxyName+#if MIN_VERSION_template_haskell(2,17,0)+      prismBinders            = fieldBinders ++ [PlainTV rs SpecifiedSpec]+#else       prismBinders            = fieldBinders ++ [PlainTV rs]+#endif    prismContext  <- cxt [ [t| RecApplicative $rsTy |], [t| $(pure fieldTypeApplied) ∈ $rsTy |] ]   prismType     <- [t| Prism' (Field $rsTy) $(pure fieldValueType) |]
test/RecordSpec.hs view
@@ -2,13 +2,15 @@  import Composite.Record import Composite.TH (withLensesAndProxies)-import Control.Lens (view, set, _Just)+import Control.Lens (set, view, _Just)+import Data.Functor.Contravariant (Predicate (Predicate, getPredicate)) import Test.Hspec (Spec, describe, it, shouldBe)  withLensesAndProxies [d|   type FFoo = "foo" :-> Int   type FBar = "bar" :-> String   |]+ type TestRec = '["foo" :-> Int, "bar" :-> String]  recordSuite :: Spec@@ -25,6 +27,12 @@           Just foo :^: Nothing :^: RNil = rec       foo `shouldBe` 123 +    it "Supports construction and deconstruction of a Rec f (Contravariant)" $ do+      let rec = Predicate even :!: Predicate (even . length) :!: RNil :: Rec Predicate TestRec+          foo :!: bar :!: RNil = rec+      getPredicate foo 123 `shouldBe` False+      getPredicate bar "foo" `shouldBe` False+     it "Supports lensing in a Rec Identity" $ do       let rec = 123 :*: "foo" :*: RNil :: Record TestRec       view (rlens fFoo_) rec `shouldBe` 123@@ -34,8 +42,14 @@      it "Supports lensing in a Rec Maybe" $ do       let rec = Just 123 :^: Nothing :^: RNil :: Rec Maybe TestRec-      view (rlens' fFoo_) rec `shouldBe` Just 123-      view (rlens' fBar_) rec `shouldBe` Nothing-      set (rlens' fFoo_ . _Just) 321   rec `shouldBe` (Just 321 :^: Nothing :^: RNil)-      set (rlens' fBar_ . _Just) "bar" rec `shouldBe` (Just 123 :^: Nothing :^: RNil)+      view (rlensCo fFoo_) rec `shouldBe` Just 123+      view (rlensCo fBar_) rec `shouldBe` Nothing+      set (rlensCo fFoo_ . _Just) 321   rec `shouldBe` (Just 321 :^: Nothing :^: RNil)+      set (rlensCo fBar_ . _Just) "bar" rec `shouldBe` (Just 123 :^: Nothing :^: RNil) +    it "Supports lensing in a Rec Predicate" $ do+      let rec = Predicate even :!: Predicate (even . length) :!: RNil :: Rec Predicate TestRec+      getPredicate (view (rlensContra fFoo_) rec) 123 `shouldBe` False+      getPredicate (view (rlensContra fBar_) rec) "foo" `shouldBe` False+      getPredicate (view (rlensContra fFoo_) (set (rlensContra fFoo_) (Predicate odd) rec)) 123 `shouldBe` True+      getPredicate (view (rlensContra fBar_) (set (rlensContra fBar_) (Predicate (odd . length)) rec)) "foo" `shouldBe` True