setters (empty) → 0.1
raw patch · 6 files changed
+172/−0 lines, 6 filesdep +basedep +mtldep +template-haskellsetup-changed
Dependencies added: base, mtl, template-haskell
Files
- Control/Monad/State/Puts.hs +11/−0
- Data/Setters.hs +58/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- Test.hs +26/−0
- setters.cabal +45/−0
+ Control/Monad/State/Puts.hs view
@@ -0,0 +1,11 @@+module Control.Monad.State.Puts+ (puts)+ where++import Control.Monad.State++-- | Puts is just an opposite to gets.+-- Compare `x <- gets field' with `puts setField newValue'.+puts :: (MonadState s m) => (a -> s -> s) -> a -> m ()+puts fn value = modify (fn value)+
+ Data/Setters.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE TemplateHaskell #-}+module Data.Setters+ (declareSetters,+ declareSetters'+ )+ where++import Data.Char+import Language.Haskell.TH++-- | Declare setters for all fields of given `data' type.+-- For example, for +--+-- > data Record = Record {+-- > ...+-- > someField :: Integer,+-- > ... }+--+-- one will automatically get+--+-- > someField :: Record -> Integer.+--+-- After calling+--+-- > $(declareSetters ''Record)+--+-- one will get+--+-- > setSomeField :: Integer -> Record -> Record.+declareSetters :: Name -> Q [Dec]+declareSetters name = do+ (TyConI (DataD _ _ _ cons _)) <- reify name+ return $ concatMap (conSetters "") cons++-- | Similar to 'declareSetters', but add data type name to all setters' names.+-- For example, one will get `setRecordSomeField' instead of `setSomeField'.+declareSetters' :: Name -> Q [Dec]+declareSetters' name = do+ (TyConI (DataD _ _ _ cons _)) <- reify name+ return $ concatMap (conSetters $ nameBase name) cons++conSetters :: String -> Con -> [Dec]+conSetters prefix (RecC _ fields) = map (fieldSetter prefix) fields+conSetters prefix _ = []++capitalize :: String -> String+capitalize [] = []+capitalize (x:xs) = toUpper x: xs++fieldSetter :: String -> (Name, Strict, Type) -> Dec+fieldSetter prefix (name, _, _) =+ let name' = mkName $ "set" ++ capitalize prefix ++ (capitalize $ nameBase name)+ record = mkName "record"+ value = mkName "value"+ body = RecUpdE (VarE record) [(name, VarE value)]+ clause = Clause [VarP value, VarP record] (NormalB body) []+ in FunD name' [clause]+
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2010, IlyaPortnov++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of IlyaPortnov nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Test.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE TemplateHaskell #-}++import Control.Monad+import Control.Monad.Trans+import Control.Monad.State++import Control.Monad.State.Puts+import Data.Setters++data Record = Record {+ count :: Int,+ flag :: Bool }+ deriving (Eq, Show)++$(declareSetters ''Record)++testState :: StateT Record IO ()+testState = do+ cnt <- gets count+ puts setCount (cnt + 1)+ puts setFlag (odd cnt)+ liftIO $ print cnt++main = do+ runStateT (replicateM 10 testState) (Record 0 False)+ return ()
+ setters.cabal view
@@ -0,0 +1,45 @@+Name: setters++Version: 0.1++Synopsis: Small (TH) library to declare setters for typical `record' data type fields.++-- A longer description of the package.+Description: Haskell declares a getter for each `record' style data type field.+ This library will help you declare setters (`setFieldName' function for `fieldName' field).++License: BSD3++License-file: LICENSE++Author: IlyaPortnov++Maintainer: portnov84@rambler.ru++-- A copyright notice.+-- Copyright: ++Category: Data++Build-type: Simple++-- Extra files to be distributed with the package, such as examples or+-- a README.+Extra-source-files: Test.hs++-- Constraint on the version of Cabal needed to build this package.+Cabal-version: >=1.6+++Library+ -- Modules exported by the library.+ Exposed-modules: Data.Setters, Control.Monad.State.Puts+ + -- Packages needed in order to build this package.+ Build-depends: base >= 3 && <= 5, mtl, template-haskell+ + -- Modules not exported by this package.+ -- Other-modules: + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.+ -- Build-tools: