@@ -5,14 +5,16 @@ module ProjectM36.ConstructedAtom where
55import ProjectM36.Base
66import ProjectM36.DataTypes.Primitive
77import GHC.Generics
8−import qualified Data.Text as T
98import qualified Data.Map as M
9+import qualified Data.Text as T
1010import Control.DeepSeq (NFData)
1111import Data.Binary
12+import Control.Applicative
1213
1314--also add haskell scripting atomable support
1415--rename this module to Atomable along with test
1516
17+{-
1618data Test1T = Test1C Int
1719 deriving (Generic, Show, Eq, Binary, NFData, Atomable)
1820
@@ -21,7 +23,7 @@ data Test2T = Test2C Int Int
2123
2224data Test3T = Test3Ca | Test3Cb
2325 deriving (Generic, Show, Eq, Binary, NFData, Atomable)
24−
26+-}
2527class (Eq a, NFData a, Binary a, Show a) => Atomable a where
2628 toAtom :: a -> Atom
2729 default toAtom :: (Generic a, AtomableG (Rep a)) => a -> Atom
@@ -32,7 +34,9 @@ class (Eq a, NFData a, Binary a, Show a) => Atomable a where
3234 fromAtom v@(ConstructedAtom _ _ args) = case fromAtomG v args of
3335 Nothing -> error "no fromAtomG traversal found"
3436 Just x -> to x
35− fromAtom v = to (fromAtomG v [])
37+ fromAtom v = case fromAtomG v [] of
38+ Nothing -> error "no fromAtomG for Atom found"
39+ Just x -> to x
3640
3741 toAtomType :: a -> AtomType
3842 default toAtomType :: (Generic a, AtomableG (Rep a)) => a -> AtomType
@@ -71,7 +75,7 @@ class AtomableG g where
7175--data type metadata
7276instance (Datatype c, AtomableG a) => AtomableG (M1 D c a) where
7377 toAtomG (M1 v) t = toAtomG v t
74− fromAtomG atom args = M1 (fromAtomG atom args)
78+ fromAtomG atom args = M1 <$> fromAtomG atom args
7579 toAtomsG = undefined
7680 toAtomTypeG _ = ConstructedAtomType (T.pack typeName) M.empty -- generics don't allow us to get the type constructor variables- alternatives?
7781 where
@@ -92,9 +96,9 @@ instance (Constructor c, AtomableG a) => AtomableG (M1 C c a) where
9296 atoms = toAtomsG v
9397 constructorName = conName (undefined :: M1 C c a x)
9498 fromAtomG atom@(ConstructedAtom dConsName _ _) args = if dName == dConsName then
95− M1 (fromAtomG atom args)
99+ M1 <$> fromAtomG atom args
96100 else
97− error "constructor name mismatch"
101+ Nothing
98102 where
99103 dName = T.pack (conName (undefined :: M1 C c a x))
100104 fromAtomG _ _ = error "unsupported generic traversal"
@@ -110,7 +114,7 @@ instance (Constructor c, AtomableG a) => AtomableG (M1 C c a) where
110114--field metadata
111115instance (Selector c, AtomableG a) => AtomableG (M1 S c a) where
112116 toAtomG = undefined
113− fromAtomG atom args = M1 (fromAtomG atom args)
117+ fromAtomG atom args = M1 <$> fromAtomG atom args
114118 toAtomsG (M1 v) = toAtomsG v
115119 toAtomTypeG (M1 v) = toAtomTypeG v
116120 toDatabaseContextExprG _ _ = undefined
@@ -120,7 +124,7 @@ instance (Selector c, AtomableG a) => AtomableG (M1 S c a) where
120124-- field data metadata
121125instance (Atomable a) => AtomableG (K1 c a) where
122126 toAtomG (K1 v) _ = toAtom v
123− fromAtomG _ args = K1 (fromAtom (headatom args))
127+ fromAtomG _ args = K1 <$> Just (fromAtom (headatom args))
124128 where headatom (x:_) = x
125129 headatom [] = error "no more atoms for constructor!"
126130 toAtomsG (K1 v) = [toAtom v]
@@ -137,7 +141,7 @@ instance (Atomable a) => AtomableG (K1 c a) where
137141
138142instance AtomableG U1 where
139143 toAtomG = undefined
140− fromAtomG _ = pure U1
144+ fromAtomG _ _ = pure U1
141145 toAtomsG _ = []
142146 toAtomTypeG = undefined
143147 toDatabaseContextExprG = undefined
@@ -147,7 +151,7 @@ instance AtomableG U1 where
147151-- product types
148152instance (AtomableG a, AtomableG b) => AtomableG (a :*: b) where
149153 toAtomG = undefined
150− fromAtomG atom args = (:*:) (fromAtomG atom [headatom args]) (fromAtomG atom (tailatoms args))
154+ fromAtomG atom args = (:*:) <$> (fromAtomG atom [headatom args]) <*> (fromAtomG atom (tailatoms args))
151155 where headatom (x:_) = x
152156 headatom [] = error "no more atoms in head for product!"
153157 tailatoms (_:xs) = xs
@@ -162,7 +166,7 @@ instance (AtomableG a, AtomableG b) => AtomableG (a :*: b) where
162166instance (AtomableG a, AtomableG b) => AtomableG (a :+: b) where
163167 toAtomG (L1 x) = toAtomG x
164168 toAtomG (R1 x) = toAtomG x
165− fromAtomG atom args = L1 (fromAtomG atom args) -- I can take both branches, match on the dconsname and return through the Either monad
169+ fromAtomG atom args = (L1 <$> fromAtomG atom args) <|> (R1 <$> fromAtomG atom args)
166170 toAtomTypeG = undefined
167171 toAtomsG (L1 x) = toAtomsG x
168172 toAtomsG (R1 x) = toAtomsG x