packages feed

lenses 0.1.7 → 0.1.8

raw patch · 2 files changed

+154/−5 lines, 2 filesdep ~basedep ~template-haskellPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base, template-haskell

API changes (from Hackage documentation)

+ Data.Lenses: infixl 0 $%
- Data.Lenses: ($=) :: MonadState s m => (m () -> b) -> s -> b
+ Data.Lenses: ($=) :: (MonadState s m) => (m () -> b) -> s -> b
- Data.Lenses: alter :: MonadState a m => (m () -> StateT r Identity b) -> (a -> a) -> r -> r
+ Data.Lenses: alter :: (MonadState a m) => (m () -> StateT r Identity b) -> (a -> a) -> r -> r
- Data.Lenses: evalFromT :: Monad m => b -> StateT b m a -> m a
+ Data.Lenses: evalFromT :: (Monad m) => b -> StateT b m a -> m a
- Data.Lenses: execInT :: Monad m => b -> StateT b m a -> m b
+ Data.Lenses: execInT :: (Monad m) => b -> StateT b m a -> m b
- Data.Lenses: fetch :: MonadState a m => r -> (m a -> StateT r Identity a) -> a
+ Data.Lenses: fetch :: (MonadState a m) => r -> (m a -> StateT r Identity a) -> a
- Data.Lenses: fromGetSet :: MonadState r m => (r -> a) -> (a -> r -> r) -> StateT a m b -> m b
+ Data.Lenses: fromGetSet :: (MonadState r m) => (r -> a) -> (a -> r -> r) -> StateT a m b -> m b
- Data.Lenses: getAndModify :: MonadState s m => (s -> s) -> m s
+ Data.Lenses: getAndModify :: (MonadState s m) => (s -> s) -> m s
- Data.Lenses: modifyAndGet :: MonadState s m => (s -> s) -> m s
+ Data.Lenses: modifyAndGet :: (MonadState s m) => (s -> s) -> m s
- Data.Lenses: to :: Functor f => a -> (c -> f (a -> b)) -> c -> f b
+ Data.Lenses: to :: (Functor f) => a -> (c -> f (a -> b)) -> c -> f b
- Data.Lenses: update :: MonadState a m => r -> (m () -> StateT r Identity b) -> a -> r
+ Data.Lenses: update :: (MonadState a m) => r -> (m () -> StateT r Identity b) -> a -> r

Files

lenses.cabal view
@@ -1,5 +1,5 @@ Name:                lenses-Version:             0.1.7+Version:             0.1.8 Author:              Job Vranish Maintainer:          jvranish@gmail.com Homepage:            http://github.com/jvranish/Lenses/tree/master@@ -16,6 +16,8 @@ Extra-Source-Files:   src-23/Data/Lenses/Template.hs   src-24/Data/Lenses/Template.hs+  src-25/Data/Lenses/Template.hs+  src-26/Data/Lenses/Template.hs  library   exposed-modules: Data.Lenses,@@ -23,13 +25,17 @@   build-depends:  base >= 4 && < 6,                   mtl >= 1.1   If impl(ghc)-     If impl (ghc >= 7.10)-       HS-Source-Dirs: src-25-       build-depends:  template-haskell >= 2.10.0.0+     If impl (ghc >= 8.0)+       HS-Source-Dirs: src-26+       build-depends:  template-haskell >= 2.11.0.0      Else+       If impl (ghc >= 7.10)+         HS-Source-Dirs: src-25+         build-depends:  template-haskell >= 2.10.0.0+       Else           If impl(ghc >= 6.12)              Hs-Source-Dirs: src-24-             Build-Depends:  template-haskell >=2.4+             Build-Depends:  template-haskell >= 2.4           Else              Hs-Source-Dirs: src-23              Build-Depends:  template-haskell >=2.2 && <2.4
+ src-26/Data/Lenses/Template.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE TemplateHaskell,+    CPP #-}++{- |+This module provides an automatic Template Haskell+routine to scour data type definitions and generate+lense objects for them automatically.++It was copied almost verbatim (2 line change) from the wonderful Data.Accessors.Template module +made by Luke Palmer, and Henning Thielemann.++You will need to add:++{\-# LANGUAGE  TemplateHaskell,+ FlexibleContexts #-\}++to the top of any modules that use this one. +-}+module Data.Lenses.Template (+   nameDeriveLenses, deriveLenses+   ) where++import Language.Haskell.TH.Syntax+  -- (Q, Exp(VarE), Pat(VarP), Dec(ValD), Name(Name), mkOccName, occString, reify, )++import Data.List (nub, )+import Data.Maybe (catMaybes, )+import Control.Monad.State+import Data.Lenses++-- |@deriveLenses n@ where @n@ is the name of a data type+-- declared with @data@ looks through all the declared fields+-- of the data type, and for each field ending in an underscore+-- generates an accessor of the same name without the underscore.+--+-- It is "nameDeriveLenses" n f where @f@ satisfies+--+-- > f (s ++ "_") = Just s+-- > f x          = Nothing    -- otherwise+--+-- For example, given the data type:+--+-- > data Score = Score { p1Score_ :: Int+-- >                    , p2Score_ :: Int+-- >                    , rounds   :: Int+-- >                    }+--+-- @deriveLenses@ will generate the following objects:+--+-- > p1Score :: (MonadState Score m) => StateT Int m b -> m b+-- > p1Score = fromGetSet p1Score_ (\x s -> s { p1Score_ = x })+-- > p2Score :: (MonadState Score m) => StateT Int m b -> m b+-- > p2Score = fromGetSet p2Score_ (\x s -> s { p2Score_ = x })+--+-- It is used with Template Haskell syntax like:+--+-- > $( deriveLenses ''TypeName )+--+-- And will generate accessors when TypeName was declared+-- using @data@ or @newtype@.+deriveLenses :: Name -> Q [Dec]+deriveLenses n = nameDeriveLenses n stripUnderscore++stripUnderscore :: String -> Maybe String+stripUnderscore s = do+    (stem,'_') <- viewR s+    return stem+  where+    -- add to break dependency with Data.List.HT+    viewR :: [a] -> Maybe ([a], a)+    viewR [] = Nothing+    viewR xs = Just (init xs, last xs)++namedFields :: Con -> [VarStrictType]+namedFields (RecC _ fs) = fs+namedFields (ForallC _ _ c) = namedFields c+namedFields _ = []++-- |@nameDeriveLenses n f@ where @n@ is the name of a data type+-- declared with @data@ and @f@ is a function from names of fields+-- in that data type to the name of the corresponding accessor. If+-- @f@ returns @Nothing@, then no accessor is generated for that+-- field.+nameDeriveLenses :: Name -> (String -> Maybe String) -> Q [Dec]+nameDeriveLenses t namer = do+    info <- reify t+    reified <- case info of+                    TyConI dec -> return dec+                    _ -> fail errmsg+    (params, cons) <- case reified of+                 DataD    _ _ params _ cons' _ -> return (params, cons')+                 NewtypeD _ _ params _ con' _  -> return (params, [con'])+                 _ -> fail errmsg+    decs <- makeAccs params . nub $ concatMap namedFields cons+    when (null decs) $ qReport False nodefmsg+    return decs++    where++    errmsg = "Cannot derive accessors for name " ++ show t ++ " because"+          ++ "\n    it is not a type declared with 'data' or 'newtype'"+          ++ "\n    Did you remember to double-tick the type as in"+          ++ "\n      $(deriveLenses ''TheType)?"++    nodefmsg = "Warning: No accessors generated from the name " ++ show t+          ++ "\n    If you are using deriveLenses rather than"+          ++ "\n    nameDeriveLenses, remember accessors are"+          ++ "\n    only generated for fields ending with an underscore"++    makeAccs :: [TyVarBndr] -> [VarStrictType] -> Q [Dec]+    makeAccs params vars =+        liftM (concat . catMaybes) $ mapM (\ (name,_,ftype) -> makeAccFromName name params ftype) vars++    transformName :: Name -> Maybe Name+    transformName (Name occ f) = do+        n <- namer (occString occ)+        return $ Name (mkOccName n) f++    makeAccFromName :: Name -> [TyVarBndr] -> Type -> Q (Maybe [Dec])+    makeAccFromName name params ftype =+        case transformName name of+            Nothing -> return Nothing+            Just n -> liftM Just $ makeAcc name params ftype n++    makeAcc ::Name -> [TyVarBndr] -> Type -> Name -> Q [Dec]+    makeAcc name params ftype accName = do+        let params' = map (\x -> case x of (PlainTV n) -> n; (KindedTV n _) -> n) params+        let appliedT = foldl AppT (ConT t) (map VarT params')+        body <- [|+                 fromGetSet+                    ( $( return $ VarE name ) )+                    ( \x s ->+                        $( return $ RecUpdE (VarE 's) [(name, VarE 'x)] ) )+                |]+        return+          [ SigD accName (ForallT (map PlainTV (b:m:params')) [ConT ''MonadState `AppT` appliedT `AppT` (VarT m)] (AppT (AppT ArrowT (AppT (AppT (AppT (ConT ''StateT) ftype) (VarT m)) (VarT b))) (AppT (VarT m) (VarT b))))+          , ValD (VarP accName) (NormalB body) []+          ]+      where+        b = mkName "b"+        m = mkName "m"++