packages feed

named-records 0.2.1 → 0.2.2

raw patch · 3 files changed

+224/−149 lines, 3 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.TH: (~>) :: RecordTemplate a b c => a -> b -> c
- Data.NamedRecord.TH: Record :: String -> Record
- Data.NamedRecord.TH: _type :: t
- Data.NamedRecord.TH: class RecordTemplate a b c | a b -> c
- Data.NamedRecord.TH: data Record
- Data.NamedRecord.TH: has :: RecordTemplate a b c => a -> b -> c
- Data.NamedRecord.TH: instance RecordTemplate ((String := Name) := Q Exp) ((String := Name) := Q Exp) [(String := Name, Maybe (Q Exp))]
- Data.NamedRecord.TH: instance RecordTemplate ((String := Name) := Q Exp) (String := Name) [(String := Name, Maybe (Q Exp))]
- Data.NamedRecord.TH: instance RecordTemplate ((String := Name) := Q Exp) [(String := Name, Maybe (Q Exp))] [(String := Name, Maybe (Q Exp))]
- Data.NamedRecord.TH: instance RecordTemplate (String := Name) ((String := Name) := Q Exp) [(String := Name, Maybe (Q Exp))]
- Data.NamedRecord.TH: instance RecordTemplate (String := Name) (String := Name) [(String := Name, Maybe (Q Exp))]
- Data.NamedRecord.TH: instance RecordTemplate (String := Name) [(String := Name, Maybe (Q Exp))] [(String := Name, Maybe (Q Exp))]
- Data.NamedRecord.TH: instance RecordTemplate Record ((String := Name) := Q Exp) (Q [Dec])
- Data.NamedRecord.TH: instance RecordTemplate Record (String := Name) (Q [Dec])
- Data.NamedRecord.TH: instance RecordTemplate Record [(String := Name, Maybe (Q Exp))] (Q [Dec])
- Data.NamedRecord.TH: record :: String -> Record
- Data.NamedRecord.TH: value :: t
+ Data.NamedRecord: (~>) :: RecordTemplate a b c => a -> b -> c
+ Data.NamedRecord: class RecordTemplate a b c | a b -> c
+ Data.NamedRecord: has :: RecordTemplate a b c => a -> b -> c
+ Data.NamedRecord: instance [overlap ok] (ToType v, ToExp d) => RecordTemplate ((String := v) := d) [(String, Q Type, Maybe (Q Exp))] [(String, Q Type, Maybe (Q Exp))]
+ Data.NamedRecord: instance [overlap ok] (ToType v, ToExp d) => RecordTemplate Record ((String := v) := d) (Q [Dec])
+ Data.NamedRecord: instance [overlap ok] (ToType v, ToType w) => RecordTemplate (String := v) (String := w) [(String, Q Type, Maybe (Q Exp))]
+ Data.NamedRecord: instance [overlap ok] (ToType v, ToType w, ToExp d) => RecordTemplate ((String := v) := d) (String := w) [(String, Q Type, Maybe (Q Exp))]
+ Data.NamedRecord: instance [overlap ok] (ToType v, ToType w, ToExp d, ToExp e) => RecordTemplate ((String := v) := d) ((String := w) := e) [(String, Q Type, Maybe (Q Exp))]
+ Data.NamedRecord: instance [overlap ok] (ToType v, ToType w, ToExp e) => RecordTemplate (String := v) ((String := w) := e) [(String, Q Type, Maybe (Q Exp))]
+ Data.NamedRecord: instance [overlap ok] Lift a => ToExp a
+ Data.NamedRecord: instance [overlap ok] RecordTemplate Record [(String, Q Type, Maybe (Q Exp))] (Q [Dec])
+ Data.NamedRecord: instance [overlap ok] ToExp (Q Exp)
+ Data.NamedRecord: instance [overlap ok] ToType (Q Type)
+ Data.NamedRecord: instance [overlap ok] ToType Name
+ Data.NamedRecord: instance [overlap ok] ToType v => RecordTemplate (String := v) [(String, Q Type, Maybe (Q Exp))] [(String, Q Type, Maybe (Q Exp))]
+ Data.NamedRecord: instance [overlap ok] ToType v => RecordTemplate Record (String := v) (Q [Dec])
+ Data.NamedRecord: record :: String -> Record
- 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 view
@@ -1,11 +1,88 @@ Name:           named-records-Version:        0.2.1+Version:        0.2.2 Synopsis:       Flexible records with named fields. Description:    Flexible records with named fields.                 .                 [@v0.2@] Default values with @record@.                 .                 [@v0.2.1@] Requires @names-0.2.1@.+                .+                [@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               +                 License:        MIT License-File:   LICENSE Author:         Julian Fleischer <julian.fleischer@fu-berlin.de>@@ -16,11 +93,10 @@ Stability:      experimental  Library-    Exposed-Modules:    Data.NamedRecord,-                        Data.NamedRecord.TH+    Exposed-Modules:    Data.NamedRecord      Build-Depends:      base >= 4 && < 5,-                        names == 0.2.1,+                        names == 0.2.2,                         template-haskell >= 2.7      Hs-Source-Dirs:     src
src/Data/NamedRecord.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE Haskell2010+    , TemplateHaskell     , MultiParamTypeClasses     , FunctionalDependencies     , TypeOperators@@ -7,14 +8,39 @@     , OverlappingInstances  #-} -module Data.NamedRecord where+module Data.NamedRecord (+    Property (get, set),+    add, +    (:=) (..),+    (:+) (..), +    record,+    has,++    RecordTemplate (..),++    module Data.Name+) where++import Data.List+import qualified Data.Name+import Data.Name (name, nameT, nameV)+import Language.Haskell.TH+import Language.Haskell.TH.Syntax (Lift (..))+++ data a := b = a := b deriving Show  infixl 3 :=  +data a :+ b = a :+ b deriving Show++infixr 2 :+++ class Property o n v | o n -> v where          get :: o -> n -> v@@ -48,8 +74,123 @@     set (a :+ b) p = a :+ (set b p)  -data a :+ b = a :+ b deriving Show -infixr 2 :++data Record = Record String++record :: String -> Record+record = Record+++class ToType a where toType :: a -> Q Type++instance ToType (Q Type) where toType = id+instance ToType Name where toType = return . ConT+++class ToExp a where toExp :: a -> Q Exp++instance ToExp (Q Exp) where toExp = id+instance Lift a => ToExp a where toExp = lift+++class RecordTemplate a b c | a b -> c where+    (~>) :: a -> b -> c+++instance (ToType v, ToType w) => RecordTemplate+        (String := v)+        (String := w)+        [(String, Q Type, Maybe (Q Exp))] where+    (n := v) ~> (m := w) = [(n, toType v, Nothing),+                            (m, toType w, Nothing)]++instance (ToType v, ToType w, ToExp e) => RecordTemplate+        (String := v)+        (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)]++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)]++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)]++instance ToType v => RecordTemplate+        (String := v)+        [(String, Q Type, Maybe (Q Exp))]+        [(String, Q Type, Maybe (Q Exp))] where+    (n := v) ~> xs = (n, toType v, Nothing) : xs++instance (ToType v, ToExp d) => RecordTemplate+        (String := v := d)+        [(String, Q Type, Maybe (Q Exp))]+        [(String, Q Type, Maybe (Q Exp))] where+    (n := v := d) ~> xs = (n, toType v, Just $ toExp d) : xs+++instance ToType v => RecordTemplate Record (String := v) (Q [Dec]) where+    r ~> (n := v) = r ~> [(n, toType v, Nothing :: Maybe (Q Exp))]++instance (ToType v, ToExp d) =>+        RecordTemplate Record (String := v := d) (Q [Dec]) where+    r ~> (n := v := d) = r ~> [(n, toType v, Just $ toExp d)]+++instance RecordTemplate+        Record [(String, Q Type, Maybe (Q Exp))] (Q [Dec]) where++    Record name ~> fs = do+        let typeD typ = TySynD (mkName name) [] typ++            func (name, valType, defaultVal) = do+                nameType <- nameT name+                valueType <- valType+                defaultValue <- maybe (return $ VarE 'value) id defaultVal+                return $ ( AppT (AppT (ConT ''(:=)) nameType) valueType+                         , defaultValue )++        fields <- mapM func+            $ sortBy (\(x, _, _) (y, _, _) -> compare x y) fs++        let syn = foldr (\(x, _) xs -> AppT (AppT (ConT ''(:+)) x) xs)+                        (fst $ last fields) (init fields)++            cName = mkName ("new" ++ name)++            sigD = SigD cName (ConT (mkName name))++            funcD = ValD (VarP cName) (NormalB funcB) []+            funcB = foldr join (field $ last fields) (init fields)+              where+                join x xs = InfixE (Just $ field x) (ConE '(:+)) (Just xs)++            field (_, x) = InfixE (Just (VarE '_type))+                             (ConE '(:=))+                             (Just x)++        return [typeD syn, sigD, funcD]+++_type = error $ "NamedRecord field type unwrapped!"+    ++ " You should never see this."+    ++ " Srsly, what did you do?"++value = error "Data.NameRecord.undefined: No value set."++has :: RecordTemplate a b c => a -> b -> c+has = (~>)++infixr 1 ~>+infixr 1 `has`  
− src/Data/NamedRecord/TH.hs
@@ -1,142 +0,0 @@-{-# LANGUAGE Haskell2010-    , MultiParamTypeClasses-    , FunctionalDependencies-    , TypeOperators-    , FlexibleInstances-    , TemplateHaskell- #-}--module Data.NamedRecord.TH where---import Data.List-import Data.NamedRecord-import Data.Name.TH-import Language.Haskell.TH---data Record = Record String--record :: String -> Record-record = Record---class RecordTemplate a b c | a b -> c where-    -    (~>) :: a -> b -> c---instance RecordTemplate-    (String := Name)-    (String := Name)-    [(String := Name, Maybe (Q Exp))] where--    a ~> b = [(a, Nothing), (b, Nothing)]---instance RecordTemplate-    (String := Name := Q Exp)-    (String := Name)-    [(String := Name, Maybe (Q Exp))] where--    (p := d) ~> b = [(p, Just d), (b, Nothing)]---instance RecordTemplate-    (String := Name)-    (String := Name := Q Exp)-    [(String := Name, Maybe (Q Exp))] where--    a ~> (p := d) = [(a, Nothing), (p, Just d)]---instance RecordTemplate-    (String := Name := Q Exp)-    (String := Name := Q Exp)-    [(String := Name, Maybe (Q Exp))] where--    (a := m) ~> (b := n) = [(a, Just m), (b, Just n)]---instance RecordTemplate-    (String := Name)-    [(String := Name, Maybe (Q Exp))]-    [(String := Name, Maybe (Q Exp))] where--    p ~> xs = (p, Nothing) : xs---instance RecordTemplate-    (String := Name := Q Exp)-    [(String := Name, Maybe (Q Exp))]-    [(String := Name, Maybe (Q Exp))] where--    (p := d) ~> xs = (p, Just d) : xs---instance RecordTemplate-    Record-    (String := Name)-    (Q [Dec]) where--    r ~> p = r ~> [(p, Nothing :: Maybe (Q Exp))]---instance RecordTemplate-    Record-    (String := Name := Q Exp)-    (Q [Dec]) where--    r ~> (p := d) = r ~> [(p, Just d)]---instance RecordTemplate-    Record-    [(String := Name, Maybe (Q Exp))]-    (Q [Dec]) where--    Record name ~> fs = do-        let typeD typ = TySynD (mkName name) [] typ--            func (name := valueType, defaultVal) = do-                nameType <- nameT name-                defaultValue <- maybe (return $ VarE 'value) id defaultVal-                return $ ( AppT (AppT (ConT ''(:=)) nameType)-                                (ConT valueType)-                         , defaultValue )--        fields <- mapM func-            $ sortBy (\(x := _, _) (y := _, _) -> compare x y) fs--        let syn = foldr (\(x, _) xs -> AppT (AppT (ConT ''(:+)) x) xs)-                        (fst $ last fields) (init fields)--            cName = mkName ("new" ++ name)--            sigD = SigD cName (ConT (mkName name))--            funcD = ValD (VarP cName) (NormalB funcB) []-            funcB = foldr join (field $ last fields) (init fields)-              where-                join x xs = InfixE (Just $ field x) (ConE '(:+)) (Just xs)--            field (_, x) = InfixE (Just (VarE '_type))-                             (ConE '(:=))-                             (Just x)--        return [typeD syn, sigD, funcD]---_type = error $ "NamedRecord field type unwrapped!"-    ++ " You should never see this."-    ++ " Srsly, what did you do?"--value = error "Data.NameRecord.undefined: No value set."--has :: RecordTemplate a b c => a -> b -> c-has = (~>)--infixr 1 ~>-infixr 1 `has`--