|
@@ -9,8 +9,8 @@ module Data.SExpression.Repr
|
|
|
) where
|
|
|
|
|
|
-- | All S-Expressions can be understood as a sequence
|
|
|
+-- of @cons@ cells (represented here by 'SCons'), the
|
|
|
+-- empty list @nil@ (represented by 'SNil') or an
|
|
|
-- @atom@.
|
|
|
data SExpr atom
|
|
|
= SCons (SExpr atom) (SExpr atom)
|
|
@@ -20,8 +20,8 @@ data SExpr atom
|
|
|
|
|
|
-- | Sometimes, the cons-based interface is too low
|
|
|
-- level, and we'd rather have the lists themselves
|
|
|
+-- exposed. In this case, we have 'RSList' to
|
|
|
+-- represent a well-formed cons list, and 'RSDotted'
|
|
|
-- to represent an improper list of the form
|
|
|
-- @(a b c . d)@.
|
|
|
data RichSExpr atom
|
|
@@ -30,6 +30,15 @@ data RichSExpr atom
|
|
|
| RSAtom atom
|
|
|
deriving (Eq, Show, Read)
|
|
|
|
|
|
+-- | A Rich S-Expression might be a nicer interface
|
|
|
+-- for certain libraries. It should always be true
|
|
|
+-- that
|
|
|
+--
|
|
|
+-- > fromRich . toRich == id
|
|
|
+--
|
|
|
+-- and that
|
|
|
+--
|
|
|
+-- > toRich . fromRich == id
|
|
|
toRich :: SExpr atom -> RichSExpr atom
|
|
|
toRich (SAtom a) = RSAtom a
|
|
|
toRich (SCons x xs) = go xs [toRich x]
|
|
@@ -37,6 +46,7 @@ toRich (SCons x xs) = go xs [toRich x]
|
|
|
go SNil rs = RSList rs
|
|
|
go (SCons x xs) rs = go xs (toRich x:rs)
|
|
|
|
|
|
+-- | This follows the same laws as 'toRich'.
|
|
|
fromRich :: RichSExpr atom -> SExpr atom
|
|
|
fromRich (RSAtom a) = SAtom a
|
|
|
fromRich (RSList xs) = foldr SCons SNil (map fromRich xs)
|
|
@@ -54,13 +64,15 @@ data WellFormedSExpr atom
|
|
|
|
|
|
-- | This will be @Nothing@ is the argument contains an
|
|
|
-- improper list. It should hold that
|
|
|
-toWellFormed :: SExpr atom -> Maybe (WellFormedSExpr atom)
|
|
|
-toWellFormed (SAtom a) = Just (WFSAtom a)
|
|
|
+--
|
|
|
+-- > toWellFormed . fromWellFormed == Right
|
|
|
+toWellFormed :: SExpr atom -> Either String (WellFormedSExpr atom)
|
|
|
+toWellFormed (SAtom a) = return (WFSAtom a)
|
|
|
toWellFormed (SCons x xs) = do
|
|
|
x' <- toWellFormed x
|
|
|
go xs [x']
|
|
|
- where go (SAtom a) rs = Nothing
|
|
|
- go SNil rs = Just (WFSList rs)
|
|
|
+ where go (SAtom a) rs = Left "Found atom in cdr position"
|
|
|
+ go SNil rs = return (WFSList rs)
|
|
|
go (SCons x xs) rs = do
|
|
|
x' <- toWellFormed x
|
|
|
go xs (x':rs)
|