packages feed

composite-base 0.4.2.0 → 0.5.0.0

raw patch · 5 files changed

+116/−13 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Composite.CoRecord: widenCoRec :: (FoldRec ss ss, RecApplicative rs, RecApplicative ss, rs ⊆ ss) => CoRec f rs -> CoRec f ss
+ Composite.CoRecord: widenField :: (FoldRec ss ss, RecApplicative rs, RecApplicative ss, rs ⊆ ss) => Field rs -> Field ss
+ Composite.Record: val :: forall (s :: Symbol) a. a -> Identity (s :-> a)
+ Control.Monad.Composite.Context: instance (Control.Monad.Composite.Context.MonadContext c m, GHC.Base.Monoid w) => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
+ Control.Monad.Composite.Context: instance (Control.Monad.Composite.Context.MonadContext c m, GHC.Base.Monoid w) => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.RWS.Strict.RWST r w s m)
+ Control.Monad.Composite.Context: instance (Control.Monad.Composite.Context.MonadContext c m, GHC.Base.Monoid w) => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.Writer.Lazy.WriterT w m)
+ Control.Monad.Composite.Context: instance (Control.Monad.Composite.Context.MonadContext c m, GHC.Base.Monoid w) => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.Writer.Strict.WriterT w m)
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c ((->) (Composite.Record.Record c))
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c m => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.Cont.ContT r m)
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c m => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.Except.ExceptT e m)
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c m => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.Identity.IdentityT m)
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c m => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.Maybe.MaybeT m)
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c m => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.Reader.ReaderT r m)
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c m => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.State.Lazy.StateT s m)
+ Control.Monad.Composite.Context: instance Control.Monad.Composite.Context.MonadContext c m => Control.Monad.Composite.Context.MonadContext c (Control.Monad.Trans.State.Strict.StateT s m)
+ Control.Monad.Composite.Context: runInContext :: Record c -> ContextT c m a -> m a

Files

composite-base.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.17.0.+-- This file has been generated from package.yaml by hpack version 0.18.1. -- -- see: https://github.com/sol/hpack  name:           composite-base-version:        0.4.2.0+version:        0.5.0.0 synopsis:       Shared utilities for composite-* packages. description:    Shared helpers for the various composite packages. category:       Records@@ -23,11 +23,11 @@   build-depends:       base >= 4.7 && < 5     , exceptions-    , template-haskell     , lens     , monad-control     , mtl     , profunctors+    , template-haskell     , text     , transformers     , transformers-base@@ -38,6 +38,8 @@       Composite.Record       Composite.TH       Control.Monad.Composite.Context+  other-modules:+      Paths_composite_base   default-language: Haskell2010  test-suite composite-base-test@@ -50,11 +52,11 @@   build-depends:       base >= 4.7 && < 5     , exceptions-    , template-haskell     , lens     , monad-control     , mtl     , profunctors+    , template-haskell     , text     , transformers     , transformers-base
src/Composite/CoRecord.hs view
@@ -8,11 +8,12 @@ import Control.Lens (Prism', prism') import Data.Functor.Identity (Identity(Identity), runIdentity) import Data.Kind (Constraint)+import Data.Maybe (fromMaybe) import Data.Profunctor (dimap) import Data.Proxy (Proxy(Proxy))-import Data.Vinyl (Dict(Dict), Rec((:&), RNil), RecApplicative, RElem, recordToList, reifyConstraint, rmap, rpure)+import Data.Vinyl.Core (Dict(Dict), Rec((:&), RNil), RecApplicative, recordToList, reifyConstraint, rmap, rpure) import Data.Vinyl.Functor (Compose(Compose, getCompose), Const(Const), (:.))-import Data.Vinyl.Lens (type (∈), rget, rput)+import Data.Vinyl.Lens (RElem, type (∈), type (⊆), rget, rput, rreplace) import Data.Vinyl.TypeLevel (RecAll, RIndex)  -- FIXME? replace with int-index/union or at least lift ideas from there. This encoding is awkward to work with and not compositional.@@ -214,3 +215,15 @@ matchField :: RecApplicative (r ': rs) => Field (r ': rs) -> Cases (r ': rs) b -> b matchField = flip foldField {-# INLINE matchField #-}++-- |Widen a @'CoRec' f rs@ to a @'CoRec' f ss@ given that @rs ⊆ ss@.+widenCoRec :: (FoldRec ss ss, RecApplicative rs, RecApplicative ss, rs ⊆ ss) => CoRec f rs -> CoRec f ss+widenCoRec r =+  fromMaybe (error "widenCoRec should be provably total, isn't") $+    firstCoRec (rreplace (coRecToRec r) (rpure $ Compose Nothing))++-- |Widen a @'Field' rs@ to a @'Field' ss@ given that @rs ⊆ ss@.+widenField :: (FoldRec ss ss, RecApplicative rs, RecApplicative ss, rs ⊆ ss) => Field rs -> Field ss+widenField r =+  fromMaybe (error "widenField should be provably total, isn't") $+    firstField (rreplace (fieldToRec r) (rpure Nothing))
src/Composite/Record.hs view
@@ -2,7 +2,7 @@ module Composite.Record   ( Rec((:&), RNil), Record   , pattern (:*:), pattern (:^:)-  , (:->)(Val, getVal), valName, valWithName+  , (:->)(Val, getVal), val, valName, valWithName   , RElem, rlens, rlens'   , AllHave, HasInstances, ValuesAllHave   , zipRecsWith, reifyDicts, recordToNonEmpty@@ -80,6 +80,35 @@  instance forall (s :: Symbol) a. (KnownSymbol s, Show a) => Show (s :-> a) where   showsPrec p (Val a) = ((symbolVal (Proxy :: Proxy s) ++ " :-> ") ++) . showsPrec p a++-- |Convenience function to make an @'Identity' (s ':->' a)@ with a particular symbol, used for named field construction.+--+-- For example:+--+-- @+--   type FFoo = "foo" :-> Int+--   type FBar = "bar" :-> String+--   type FBaz = "baz" :-> Double+--   type MyRecord = [FFoo, FBar, FBaz]+--+--   myRecord1 :: Record MyRecord+--   myRecord1+--     =  val @"foo" 123+--     :& val @"bar" "foobar"+--     :& val @"baz" 3.21+--     :& RNil+--+--   myRecord2 :: Record MyRecord+--   myRecord2 = rcast+--     $  val @"baz" 3.21+--     :& val @"foo" 123+--     :& val @"bar" "foobar"+--     :& RNil+-- @+--+-- In this example, both @myRecord1@ and @myRecord2@ have the same value, since 'Data.Vinyl.Lens.rcast' can reorder records.+val :: forall (s :: Symbol) a. a -> Identity (s :-> a)+val = Identity . Val @s  -- |Reflect the type level name of a named value @s :-> a@ to a @Text@. For example, given @"foo" :-> Int@, yields @"foo" :: Text@ valName :: forall s a. KnownSymbol s => s :-> a -> Text
src/Control/Monad/Composite/Context.hs view
@@ -3,7 +3,7 @@  -- |Module with a `ReaderT` style monad specialized to holding a record. module Control.Monad.Composite.Context-  ( ContextT(ContextT, runContextT), withContext, mapContextT+  ( ContextT(ContextT, runContextT), runInContext, withContext, mapContextT   , MonadContext(askContext, localContext), asksContext, askField   ) where @@ -13,18 +13,30 @@ import Control.Monad (MonadPlus(mzero, mplus)) import Control.Monad.Base (MonadBase(liftBase)) import Control.Monad.Catch (MonadThrow(throwM), MonadCatch(catch), MonadMask(mask, uninterruptibleMask))+import Control.Monad.Cont (ContT(ContT), runContT) import Control.Monad.Cont.Class (MonadCont(callCC)) import Control.Monad.Error.Class (MonadError(throwError, catchError))+import Control.Monad.Except (ExceptT(ExceptT), runExceptT) import Control.Monad.Fail (MonadFail) import qualified Control.Monad.Fail as MonadFail import Control.Monad.Fix (MonadFix(mfix)) import Control.Monad.IO.Class (MonadIO(liftIO))+import Control.Monad.Reader (ReaderT(ReaderT), runReaderT) import Control.Monad.Reader.Class (MonadReader(local, ask, reader))+import qualified Control.Monad.RWS.Lazy as Lazy+import qualified Control.Monad.RWS.Strict as Strict import Control.Monad.RWS.Class (MonadRWS)+import qualified Control.Monad.State.Lazy as Lazy+import qualified Control.Monad.State.Strict as Strict import Control.Monad.State.Class (MonadState(get, put, state)) import Control.Monad.Trans.Class (MonadTrans(lift)) import Control.Monad.Trans.Control (MonadTransControl(type StT, liftWith, restoreT), MonadBaseControl(type StM, liftBaseWith, restoreM))+import Control.Monad.Trans.Identity (IdentityT(IdentityT), runIdentityT)+import Control.Monad.Trans.Maybe (MaybeT(MaybeT), runMaybeT)+import qualified Control.Monad.Writer.Lazy as Lazy+import qualified Control.Monad.Writer.Strict as Strict import Control.Monad.Writer.Class (MonadWriter(writer, tell, listen, pass))+import Data.Monoid (Monoid)  -- |Class of monad (stacks) which have context reading functionality baked in. Similar to 'Control.Monad.Reader.MonadReader' but can coexist with a -- another monad that provides 'Control.Monad.Reader.MonadReader' and requires the context to be a record.@@ -35,6 +47,54 @@   -- |Run some action which has the same type of context with the context modified.   localContext :: (Record c -> Record c) -> m a -> m a +instance MonadContext c ((->) (Record c)) where+  askContext = id+  localContext f = (. f)++instance MonadContext c m => MonadContext c (ReaderT r m) where+  askContext = lift askContext+  localContext f m = ReaderT $ \ r -> localContext f (runReaderT m r)++instance MonadContext c m => MonadContext c (MaybeT m) where+  askContext = lift askContext+  localContext f m = MaybeT $ localContext f (runMaybeT m)++instance (MonadContext c m, Monoid w) => MonadContext c (Strict.WriterT w m) where+  askContext = lift askContext+  localContext f m = Strict.WriterT $ localContext f (Strict.runWriterT m)++instance (MonadContext c m, Monoid w) => MonadContext c (Lazy.WriterT w m) where+  askContext = lift askContext+  localContext f m = Lazy.WriterT $ localContext f (Lazy.runWriterT m)++instance MonadContext c m => MonadContext c (Strict.StateT s m) where+  askContext = lift askContext+  localContext f m = Strict.StateT $ \ s -> localContext f (Strict.runStateT m s)++instance MonadContext c m => MonadContext c (Lazy.StateT s m) where+  askContext = lift askContext+  localContext f m = Lazy.StateT $ \ s -> localContext f (Lazy.runStateT m s)++instance MonadContext c m => MonadContext c (IdentityT m) where+  askContext = lift askContext+  localContext f m = IdentityT $ localContext f (runIdentityT m)++instance MonadContext c m => MonadContext c (ExceptT e m) where+  askContext = lift askContext+  localContext f m = ExceptT $ localContext f (runExceptT m)++instance MonadContext c m => MonadContext c (ContT r m) where+  askContext = lift askContext+  localContext f m = ContT $ \ k -> localContext f (runContT m k)++instance (MonadContext c m, Monoid w) => MonadContext c (Strict.RWST r w s m) where+  askContext = lift askContext+  localContext f m = Strict.RWST $ \ r s -> localContext f (Strict.runRWST m r s)++instance (MonadContext c m, Monoid w) => MonadContext c (Lazy.RWST r w s m) where+  askContext = lift askContext+  localContext f m = Lazy.RWST $ \ r s -> localContext f (Lazy.runRWST m r s)+ -- |Project some value out of the context using a function. asksContext :: MonadContext c m => (Record c -> a) -> m a asksContext f = f <$> askContext@@ -45,6 +105,10 @@  -- |Monad transformer which adds an implicit environment which is a record. Isomorphic to @ReaderT (Record c) m@. newtype ContextT (c :: [*]) (m :: (* -> *)) a = ContextT { runContextT :: Record c -> m a }++-- |Run some action in a given context, equivalent to 'runContextT' but with the arguments flipped.+runInContext :: Record c -> ContextT c m a -> m a+runInContext = flip runContextT  -- |Permute the current context with a function and then run some action with that modified context. withContext :: (Record c' -> Record c) -> ContextT c m a -> ContextT c' m a
test/RecordSpec.hs view
@@ -25,11 +25,6 @@           Just foo :^: Nothing :^: RNil = rec       foo `shouldBe` 123 -    it "Supports pattern matching an Identity .: (:->)" $ do-      let val = Val (123 :: Int)-          Val i = val-      i `shouldBe` 123-     it "Supports lensing in a Rec Identity" $ do       let rec = 123 :*: "foo" :*: RNil :: Record TestRec       view (rlens fFoo_) rec `shouldBe` 123