on master help sign in
WIP compilation checkpoint

toAttributesG is causing "toAttributes (undefined :: Test)" to be evaluated

commitc413bf087f3891d0096f336eaf51cce97d958720 authorAgentM <agentm@themactionfaction.com> dateWed 23 Aug 2017, 17:26 (9 years ago) parent42746d8
5 files changed+182−92
examples/out_of_the_tarpit.hs+91−62 src/lib/ProjectM36/Client.hs+1−1 src/lib/ProjectM36/Tuple.hs+3 src/lib/ProjectM36/Tupleable.hs+20−17 test/Relation/Tupleable.hs+67−12
examples/out_of_the_tarpit.hs+91−62
@@ -2,50 +2,35 @@
22{-# LANGUAGE DeriveAnyClass, DeriveGeneric, OverloadedStrings #-}
33import ProjectM36.Client
44import ProjectM36.DataTypes.Primitive
5−import qualified Data.Map as M
5+import ProjectM36.Tupleable
66import Data.Either
77import Control.Monad
88import GHC.Generics
99import Data.Binary
1010import Control.DeepSeq
11+import qualified Data.Text as T
12+import Data.Time.Calendar (Day)
13+import qualified Data.Vector as V
1114
1215--create various database value (atom) types
13−addressAtomType :: AtomType
14−addressAtomType = TextAtomType
16+type Price = Double
1517
16−nameAtomType :: AtomType
17−nameAtomType = TextAtomType
18+type Name = T.Text
1819
19−priceAtomType :: AtomType
20−priceAtomType = DoubleAtomType
20+type Address = T.Text
2121
22−fileNameAtomType :: AtomType
23−fileNameAtomType = TextAtomType
24−
25−data Room = Kitchen | Bathroom | LivingRoom
22+data RoomType = Kitchen | Bathroom | LivingRoom
2623 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
2724
28−roomAtomType :: AtomType
29−roomAtomType = toAtomType (undefined :: Room)
30−
3125data PriceBand = Low | Medium | High | Premium
3226 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
3327
34−priceBandAtomType :: AtomType
35−priceBandAtomType = toAtomType (undefined :: PriceBand)
36−
3728data AreaCode = City | Suburban | Rural
3829 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
3930
40−areaCodeAtomType :: AtomType
41−areaCodeAtomType = ConstructedAtomType "AreaCode" M.empty
42−
4331data SpeedBand = VeryFastBand | FastBand | MediumBand | SlowBand
4432 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
4533
46−speedBandAtomType :: AtomType
47−speedBandAtomType = ConstructedAtomType "SpeedBand" M.empty
48−
4934main :: IO ()
5035main = do
5136 --connect to the database
@@ -62,38 +47,82 @@ main = do
6247
6348 createSchema sessionId conn
6449
50+data Test = Test {
51+ dateo :: Int,
52+ date2o :: Int
53+ }
54+ deriving (Generic, Eq)
55+
56+instance Tupleable Test
57+
58+data Property = Property {
59+ address :: T.Text,
60+ price :: Price,
61+ photo :: T.Text,
62+ dateRegistered :: Day
63+ }
64+ deriving (Generic, Eq)
65+
66+instance Tupleable Property
67+
68+data Offer = Offer {
69+ offerAddress :: Address,
70+ offerPrice :: Price,
71+ offerDate :: Day,
72+ bidderName :: Name,
73+ bidderAddress :: Address,
74+ decisionDate :: Day,
75+ accepted :: Bool
76+ }
77+ deriving (Generic, Eq)
78+
79+instance Tupleable Offer
80+
81+data Decision = Decision {
82+ dec_address :: Address,
83+ dec_offerDate :: Day, --the dec_ prefix is needed until OverloadedRecordFields is available
84+ dec_bidderName :: Name,
85+ dec_bidderAddress :: Address,
86+ dec_decisionDate :: Day,
87+ dec_accepted :: Bool
88+ }
89+ deriving (Generic, Eq)
90+
91+instance Tupleable Decision
92+
93+data Room = Room {
94+ room_address :: Address,
95+ roomName :: Name,
96+ width :: Double,
97+ breadth :: Double,
98+ roomType :: RoomType
99+ }
100+ deriving (Generic, Eq)
101+
102+instance Tupleable Room
103+
104+data Floor = Floor {
105+ floor_address :: Address,
106+ floor_roomName :: Name,
107+ floor :: Int
108+ }
109+ deriving (Generic, Eq)
110+
111+instance Tupleable Floor
112+
113+data Commission = Commission {
114+ priceBand :: PriceBand,
115+ areaCode :: AreaCode,
116+ saleSpeed :: SpeedBand,
117+ commission :: Price
118+ } deriving (Generic, Eq)
119+
120+instance Tupleable Commission
121+
65122createSchema :: SessionId -> Connection -> IO ()
66123createSchema sessionId conn = do
67124 --create attributes for relvars
68− let propertyAttrs = [Attribute "address" addressAtomType,
69− Attribute "price" priceAtomType,
70− Attribute "photo" fileNameAtomType,
71− Attribute "dateRegistered" DayAtomType]
72− offerAttrs = [Attribute "address" addressAtomType,
73− Attribute "offerPrice" priceAtomType,
74− Attribute "offerDate" DayAtomType,
75− Attribute "bidderName" nameAtomType,
76− Attribute "bidderAddress" addressAtomType,
77− Attribute "decisionDate" DayAtomType,
78− Attribute "accepted" BoolAtomType]
79− decisionAttrs = [Attribute "address" addressAtomType,
80− Attribute "offerDate" DayAtomType,
81− Attribute "bidderName" nameAtomType,
82− Attribute "bidderAddress" addressAtomType,
83− Attribute "decisionDate" DayAtomType,
84− Attribute "accepted" BoolAtomType]
85− roomAttrs = [Attribute "address" addressAtomType,
86− Attribute "roomName" TextAtomType,
87− Attribute "width" DoubleAtomType,
88− Attribute "breadth" DoubleAtomType,
89− Attribute "type" roomAtomType]
90− floorAttrs = [Attribute "address" addressAtomType,
91− Attribute "roomName" TextAtomType,
92− Attribute "floor" IntAtomType]
93− commissionAttrs = [Attribute "priceBand" priceBandAtomType,
94− Attribute "areaCode" areaCodeAtomType,
95− Attribute "saleSpeed" speedBandAtomType,
96− Attribute "commission" DoubleAtomType]
125+ let
97126 --create uniqueness constraints
98127 incDepKeys = map (uncurry databaseContextExprForUniqueKey)
99128 [("property", ["address"]),
@@ -120,15 +149,15 @@ createSchema sessionId conn = do
120149 ]
121150 incDepForeignKeys = map (\(n, a, b) -> databaseContextExprForForeignKey n a b) foreignKeys
122151 --define the relvars
123− relvarMap = [("property", propertyAttrs),
124− ("offer", offerAttrs),
125− ("decision", decisionAttrs),
126− ("room", roomAttrs),
127− ("floor", floorAttrs),
128− ("commission", commissionAttrs)]
129− rvDefs = map (\(name, attrs) -> Define name (map NakedAttributeExpr attrs)) relvarMap
152+ relvarMap = [("property", toAttributes (undefined :: Property)),
153+ ("offer", toAttributes (undefined :: Offer)),
154+ ("decision", toAttributes (undefined :: Decision)),
155+ ("room", toAttributes (undefined :: Room)),
156+ ("floor", toAttributes (undefined :: Floor)),
157+ ("commission", toAttributes (undefined :: Commission))]
158+ rvDefs = map (\(name, typ) -> Define name (map NakedAttributeExpr (V.toList typ))) relvarMap
130159 --create the new algebraic data types
131− new_adts = [toDatabaseContextExpr (undefined :: Room),
160+ new_adts = [toDatabaseContextExpr (undefined :: RoomType),
132161 toDatabaseContextExpr (undefined :: PriceBand),
133162 toDatabaseContextExpr (undefined :: AreaCode),
134163 toDatabaseContextExpr (undefined :: SpeedBand)]
@@ -143,8 +172,8 @@ createSchema sessionId conn = do
143172 --gather up and execute all database updates
144173 eErrs <- mapM (executeDatabaseContextExpr sessionId conn) (new_adts ++ rvDefs ++ incDepKeys ++ incDepForeignKeys)
145174 let errs = lefts eErrs
146− unless (null errs) (error (show errs))
175+ unless (null errs) (putStrLn (show errs))
147176
148177 eErrs' <- mapM (executeDatabaseContextIOExpr sessionId conn) atomFuncs
149178 let errs' = lefts eErrs'
150− unless (null errs') (error (show errs'))
179+ unless (null errs') (putStrLn (show errs'))
src/lib/ProjectM36/Client.hs+1−1
@@ -89,7 +89,7 @@ module ProjectM36.Client
8989 Atomable(..),
9090 TupleExprBase(..),
9191 AtomExprBase(..),
92− RestrictionPredicateExprBase(..)
92+ RestrictionPredicateExprBase(..),
9393 ) where
9494import ProjectM36.Base hiding (inclusionDependencies) --defined in this module as well
9595import qualified ProjectM36.Base as B
src/lib/ProjectM36/Tuple.hs+3
@@ -209,3 +209,6 @@ reorderTuple attrs tupIn = if tupleAttributes tupIn == attrs then
209209 Left _ -> error "logic failure in reorderTuple"
210210 Right atom -> atom
211211
212+--used in Generics derivation for ADTs without named attributes
213+trimTuple :: Int -> RelationTuple -> RelationTuple
214+trimTuple index (RelationTuple attrs vals) = RelationTuple (V.drop index attrs) (V.drop index vals)
src/lib/ProjectM36/Tupleable.hs+20−17
@@ -1,17 +1,13 @@
1−{-# LANGUAGE DeriveGeneric, DefaultSignatures, FlexibleInstances, FlexibleContexts, TypeOperators, UndecidableInstances #-}
1+{-# LANGUAGE DeriveGeneric, DefaultSignatures, FlexibleInstances, FlexibleContexts, TypeOperators, UndecidableInstances, ScopedTypeVariables #-}
22module ProjectM36.Tupleable where
33import ProjectM36.Base
44import ProjectM36.Tuple
55import ProjectM36.Atomable
6−import ProjectM36.Attribute
6+import ProjectM36.Attribute hiding (null)
77import GHC.Generics
88import qualified Data.Vector as V
99import qualified Data.Text as T
1010import Data.Monoid
11−import Data.Proxy
12−import Data.Maybe
13−import ProjectM36.DataTypes.Primitive
14−import Debug.Trace
1511
1612data Test1T = Test1C {
1713 attrA :: Int
@@ -28,6 +24,10 @@ instance (Atomable a, Atomable b, Show a, Show b) => Tupleable (Test2T a b)
2824
2925instance Tupleable Test1T
3026
27+data TestUnnamed1 = TestUnnamed1 Int Double T.Text
28+ deriving (Show,Eq, Generic)
29+
30+instance Tupleable TestUnnamed1
3131
3232class Tupleable a where
3333 toTuple :: a -> RelationTuple
@@ -53,7 +53,7 @@ class TupleableG g where
5353--data type metadata
5454instance (Datatype c, TupleableG a) => TupleableG (M1 D c a) where
5555 toTupleG (M1 v) = toTupleG v
56− toAttributesG = undefined
56+ toAttributesG (M1 v) = toAttributesG v
5757 fromTupleG v = M1 (fromTupleG v)
5858
5959--constructor metadata
@@ -67,36 +67,39 @@ instance (Constructor c, TupleableG a, AtomableG a) => TupleableG (M1 C c a) whe
6767 else
6868 attr) counter attrsToCheck
6969 atoms = V.fromList (toAtomsG v)
70− toAttributesG = undefined
70+ toAttributesG (M1 v) = toAttributesG v
7171 fromTupleG tup = M1 (fromTupleG tup)
7272
7373-- product types
7474instance (TupleableG a, TupleableG b) => TupleableG (a :*: b) where
75− toTupleG = undefined
75+ toTupleG = error "toTupleG"
7676 toAttributesG (x :*: y) = toAttributesG x V.++ toAttributesG y
77− fromTupleG = undefined
77+ fromTupleG tup = fromTupleG tup :*: fromTupleG (trimTuple 1 tup)
7878
7979--selector/record
8080instance (Selector c, AtomableG a) => TupleableG (M1 S c a) where
81− toTupleG = undefined
81+ toTupleG = error "toTupleG"
8282 toAttributesG m@(M1 v) = V.singleton (Attribute name aType)
8383 where
8484 name = T.pack (selName m)
8585 aType = toAtomTypeG v
86− fromTupleG tup = case atomForAttributeName (T.pack name) tup of
87− Left _ -> error "no such record name"
86+ fromTupleG tup = if null name then -- non-record type, just pull off the first tuple item
87+ M1 (atomv (V.head (tupleAtoms tup)))
88+ else
89+ case atomForAttributeName (T.pack name) tup of
90+ Left _ -> error ("no such record name: " ++ name)
8891 Right atom -> M1 (atomv atom)
8992 where
9093 atomv atom = case fromAtomG atom [atom] of
9194 Nothing -> error "no such atom conversion"
9295 Just v -> v
9396 name = selName (undefined :: M1 S c a x)
94− --name = "attrA"
95−
9697
9798--constructors with no arguments
9899--basically useless but orthoganal to relationTrue
99100instance TupleableG U1 where
100− toTupleG = undefined
101+ toTupleG _= emptyTuple
101102 toAttributesG _ = emptyAttributes
102− fromTupleG = undefined
103+ fromTupleG _ = U1
104+
105+
test/Relation/Tupleable.hs+67−12
@@ -1,33 +1,49 @@
1−{-# LANGUAGE DeriveGeneric, DefaultSignatures, FlexibleInstances, FlexibleContexts, TypeOperators #-}
1+{-# LANGUAGE DeriveGeneric, DefaultSignatures, FlexibleInstances, FlexibleContexts, TypeOperators, DeriveAnyClass #-}
22import Test.HUnit
33import ProjectM36.Tupleable
4+import ProjectM36.Atomable
5+import Data.Binary
46import ProjectM36.Base
5−import TutorialD.Interpreter.TestBase
7+import Control.DeepSeq (NFData)
68import GHC.Generics
9+import qualified Data.Vector as V
10+import qualified Data.Map as M
11+import qualified Data.Text as T
12+import System.Exit
713
814data Test1T = Test1C {
915 attrA :: Int
1016 }
11− deriving (Generic)
17+ deriving (Generic, Eq, Show)
1218
1319data Test2T = Test2C {
1420 attrB :: Int,
1521 attrC :: Int
1622 }
17− deriving (Generic)
23+ deriving (Generic, Eq, Show)
1824
1925data Test3T = Test3C Int
20− deriving Generic
26+ deriving (Generic, Eq, Show)
2127
2228data Test4T = Test4C
23− deriving Generic
29+ deriving (Generic, Eq, Show)
2430
2531data Test5T = Test5C1 Int |
2632 Test5C2 Int
27− deriving Generic
33+ deriving (Generic, Eq, Show)
2834
2935data Test6T = Test6C T.Text Int Double
30− deriving Generic
36+ deriving (Generic, Eq, Show)
37+
38+data Test7A = Test7AC Int
39+ deriving (Generic, Show, Eq, Binary, NFData, Atomable)
40+
41+
42+data Test7T = Test7C Test7A
43+ deriving (Generic, Show, Eq)
44+
45+data Test8T = Test8C
46+ deriving (Generic, Show, Eq)
3147
3248instance Tupleable Test1T
3349
@@ -41,15 +57,54 @@ instance Tupleable Test4T
4157
4258instance Tupleable Test6T
4359
60+instance Tupleable Test7T
61+
62+instance Tupleable Test8T
63+
4464main :: IO ()
4565main = do
4666 tcounts <- runTestTT testList
4767 if errors tcounts + failures tcounts > 0 then exitFailure else exitSuccess
4868
4969testList :: Test
50−testList = TestList [testADT1]
70+testList = TestList [testADT1, testADT2, testADT3, testADT4, testADT6, testADT7, testADT8]
5171
5272testADT1 :: Test
53−testADT1 = TestCase $ do
54− let example = Test1C {attr1 = 3}
55− assertEqual "one arg constructor" example (fromTuple (toTuple example))
73+testADT1 = TestCase $ assertEqual "one record constructor" example (fromTuple (toTuple example))
74+ where
75+ example = Test1C {attrA = 3}
76+
77+
78+testADT2 :: Test
79+testADT2 = TestCase $ assertEqual "two record constructor" example (fromTuple (toTuple example))
80+ where
81+ example = Test2C { attrB = 4, attrC = 6 }
82+
83+testADT3 :: Test
84+testADT3 = TestCase $ assertEqual "one arg constructor" example (fromTuple (toTuple example))
85+ where
86+ example = Test3C 4
87+
88+testADT4 :: Test
89+testADT4 = TestCase $ assertEqual "zero arg constructor" example (fromTuple (toTuple example))
90+ where
91+ example = Test4C
92+
93+--testADT5 should not compile
94+
95+testADT6 :: Test
96+testADT6 = TestCase $ assertEqual "mixed types" example (fromTuple (toTuple example))
97+ where
98+ example = Test6C "testo" 3 4.0
99+
100+testADT7 :: Test
101+testADT7 = TestCase $ do
102+ let example = Test7C (Test7AC 3)
103+ assertEqual "atom type" example (fromTuple (toTuple example))
104+ let expectedAttrs = V.singleton (Attribute "" (ConstructedAtomType "Test7A" M.empty))
105+ assertEqual "adt atomtype" expectedAttrs (toAttributes (undefined :: Test7T))
106+
107+testADT8 :: Test
108+testADT8 = TestCase $ assertEqual "single value" example (fromTuple (toTuple example))
109+ where
110+ example = Test8C