named-records 0.2.2 → 0.2.3
raw patch · 2 files changed
+133/−80 lines, 2 filesdep ~namesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: names
API changes (from Hackage documentation)
+ Data.NamedRecord: name :: String -> Q [Dec]
+ Data.NamedRecord: nameT :: String -> Q Type
+ Data.NamedRecord: nameV :: String -> Q Exp
- Data.NamedRecord: (:+) :: a -> b -> (:+) a b
+ Data.NamedRecord: (:+) :: a -> b -> :+ a b
- Data.NamedRecord: (:=) :: a -> b -> (:=) a b
+ Data.NamedRecord: (:=) :: a -> b -> := a b
Files
- named-records.cabal +20/−76
- src/Data/NamedRecord.hs +113/−4
named-records.cabal view
@@ -1,87 +1,20 @@ Name: named-records-Version: 0.2.2+Version: 0.2.3 Synopsis: Flexible records with named fields. Description: Flexible records with named fields. .- [@v0.2@] Default values with @record@.+ [@v0.1@] Initial (not published on cabal). .- [@v0.2.1@] Requires @names-0.2.1@.+ [@v0.2@] @record@ allows for default values now. .+ [@v0.2.1@] Requires @names-0.2.1@ now.+ . [@v0.2.2@] TH @record@ definitions allow for more types to be used in the definition. .- Named records allow you to define und use records- with labeled fields. These records are first class- objects. Record fields are labeled by names, which- can basically be any type. However, the names package- provides global name types and some syntactic sugar- to use them.- .- Here is a complete walk-through, with Template Haskell- syntactic sugar.- .- This is how a typical example preamble looks like:- .- > {-# LANGUAGE Haskell2010, TemplateHaskell #-}- > - > import qualified Data.Name- > import Data.NamedRecord- .- In order to use names you need to declare them first- (see the @names@ package for further details):- .- > name "firstName"- > name "lastName"- .- These are two records @Person@ and @User@:- .- > record "Person"- > `has` "firstName" := ''String- > `has` "lastName" := ''String- >- > record "User"- > `has` "firstName" := ''String- > `has` "lastName" := ''String- > `has` "loginName" := ''String- .- Note that these declarations create constructor- functions @newPerson@ and @newUser@, as well as- type synonyms @Person@ and @User@ (use @-ddump-slices@- to see what has been generated).- .- Here are two instances of these recors:- . - > julian = newPerson- > `set` firstName := "Julian"- > `set` lastName := "Fleischer"- >- > alexander = newUser- > `set` firstName := "Alexander"- > `set` lastName := "Carnicero"- > `set` loginName := "alexander.carnicero"- .- We can now create a @displayName@ function like- the following:- .- > displayName obj =- > (obj `get` firstName) ++ " " ++- > (obj `get` lastName)- .- Note that this function will accept any record- that has a @firstName@ and a @lastName@ field of- type @String@.- .- >>> displayName julian- Julian Fleischer- .- >>> displayName alexander- Alexander Carnicero- .- As mentioned above, records are first class citizens.- That means you can create them anywhere:- .- >>> displayName (firstName := "John" :+ lastName := "Doe")- John Doe + [@v0.2.3@] Cabal package tidied up and basic+ documentation added (also fixed a bug regarding+ definition of default values). License: MIT License-File: LICENSE@@ -92,11 +25,22 @@ Category: Data, Records Stability: experimental ++Source-Repository head+ type: darcs+ location: hub.darcs.net:names++Source-Repository head+ type: darcs+ location: hub.darcs.net:names+ tag: v0.2.3++ Library Exposed-Modules: Data.NamedRecord Build-Depends: base >= 4 && < 5,- names == 0.2.2,+ names == 0.2.3, template-haskell >= 2.7 Hs-Source-Dirs: src
src/Data/NamedRecord.hs view
@@ -8,6 +8,106 @@ , OverlappingInstances #-} +{- | Flexible records with named fields.++Named records allow you to define und use records+with labeled fields. These records are first class+objects. Record fields are labeled by names, which+can basically be any type. However, the names package+provides global name types and some syntactic sugar+to use them.++Here is a complete walk-through, with Template Haskell+syntactic sugar.++This is how a typical example preamble looks like:++> import qualified Data.Name+> import Data.NamedRecord++In order to use names you need to declare them first+(see the @names@ package for further details):++> name "firstName"+> name "lastName"++These are two records @Person@ and @User@:++> record "Person"+> `has` "firstName" := ''String+> `has` "lastName" := ''String+>+> record "User"+> `has` "firstName" := ''String+> `has` "lastName" := ''String+> `has` "loginName" := ''String++Note that these declarations create constructor+functions @newPerson@ and @newUser@, as well as+type synonyms @Person@ and @User@ (use @-ddump-splices@+to see what has been generated).++Here are two instances of these recors:++> julian = newPerson+> `set` firstName := "Julian"+> `set` lastName := "Fleischer"+>+> alexander = newUser+> `set` firstName := "Alexander"+> `set` lastName := "Carnicero"+> `set` loginName := "alexander.carnicero"++We can now create a @displayName@ function like+the following:++> displayName obj =+> (obj `get` firstName) ++ " " +++> (obj `get` lastName)++Note that this function will accept any record+that has a @firstName@ and a @lastName@ field of+type @String@.++>>> displayName julian+Julian Fleischer++>>> displayName alexander+Alexander Carnicero++As mentioned above, records are first class citizens.+That means you can create them anywhere:++>>> displayName (firstName := "John" :+ lastName := "Doe")+John Doe++It is also possible to declare default values:++> name "serverName"+> name "port"+> +> record "ServerConfig"+> `has` "serverName" := ''String := "localhost"+> `has` "port" := ''Int := (4711 :: Int)++>>> newServerConfig+serverName := "localhost" :+ port := 4711++>>> newServerConfig `set` serverName := "example.org"+serverName := "example.org" :+ port := 4711++>>> newServerConfig `get` port+4711++Complex expressions and types need to be quoted using+@[e| expr |]@ and @[t| type |]@ like so:++> record "Server"+> `has` "requestHandler" := [t| Request -> Response |]+> := [e| \x -> answer x |]+> `has` "config" := ''Config := [e| newConfig |]++-} module Data.NamedRecord ( Property (get, set), add,@@ -15,12 +115,21 @@ (:=) (..), (:+) (..), + -- * Template Haskell Syntactic Sugar++ -- | Declares a record (looks like a new keyword @record@).+ -- See the examples. record,++ -- | Declares a field of a record. Use as infix operators.+ -- See the examples. has, RecordTemplate (..), - module Data.Name+ -- ** Names+ -- For convenience, this module re-exports name TH name functions.+ name, nameT, nameV ) where import Data.List@@ -109,21 +218,21 @@ (String := w := e) [(String, Q Type, Maybe (Q Exp))] where (n := v) ~> (m := w := e) = [(n, toType v, Nothing),- (n, toType w, Just $ toExp e)]+ (m, toType w, Just $ toExp e)] instance (ToType v, ToType w, ToExp d) => RecordTemplate (String := v := d) (String := w) [(String, Q Type, Maybe (Q Exp))] where (n := v := d) ~> (m := w) = [(n, toType v, Just $ toExp d),- (n, toType w, Nothing)]+ (m, toType w, Nothing)] instance (ToType v, ToType w, ToExp d, ToExp e) => RecordTemplate (String := v := d) (String := w := e) [(String, Q Type, Maybe (Q Exp))] where (n := v := d) ~> (m := w := e) = [(n, toType v, Just $ toExp d),- (n, toType w, Just $ toExp e)]+ (m, toType w, Just $ toExp e)] instance ToType v => RecordTemplate (String := v)