Repr.hs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. module Data.SExpression.Repr
  2. ( SExpr(..)
  3. , RichSExpr(..)
  4. , toRich
  5. , fromRich
  6. , WellFormedSExpr(..)
  7. , toWellFormed
  8. , fromWellFormed
  9. ) where
  10. -- | All S-Expressions can be understood as a sequence
  11. -- of @cons@ cells (represented here by @SCons@), the
  12. -- empty list @nil@ (represented by @SNil@) or an
  13. -- @atom@.
  14. data SExpr atom
  15. = SCons (SExpr atom) (SExpr atom)
  16. | SAtom atom
  17. | SNil
  18. deriving (Eq, Show, Read)
  19. -- | Sometimes, the cons-based interface is too low
  20. -- level, and we'd rather have the lists themselves
  21. -- exposed. In this case, we have @RSList@ to
  22. -- represent a well-formed cons list, and @RSDotted@
  23. -- to represent an improper list of the form
  24. -- @(a b c . d)@.
  25. data RichSExpr atom
  26. = RSList [RichSExpr atom]
  27. | RSDotted [RichSExpr atom] atom
  28. | RSAtom atom
  29. deriving (Eq, Show, Read)
  30. toRich :: SExpr atom -> RichSExpr atom
  31. toRich (SAtom a) = RSAtom a
  32. toRich (SCons x xs) = go xs [toRich x]
  33. where go (SAtom a) rs = RSDotted rs a
  34. go SNil rs = RSList rs
  35. go (SCons x xs) rs = go xs (toRich x:rs)
  36. fromRich :: RichSExpr atom -> SExpr atom
  37. fromRich (RSAtom a) = SAtom a
  38. fromRich (RSList xs) = foldr SCons SNil (map fromRich xs)
  39. fromRich (RSDotted xs x) = foldr SCons (SAtom x) (map fromRich xs)
  40. -- | A well-formed s-expression is one which does not
  41. -- contain any dotted lists. This means that not
  42. -- every value of @SExpr a@ can be converted to a
  43. -- @WellFormedSExpr a@, although the opposite is
  44. -- fine.
  45. data WellFormedSExpr atom
  46. = WFSList [WellFormedSExpr atom]
  47. | WFSAtom atom
  48. deriving (Eq, Show, Read)
  49. -- | This will be @Nothing@ is the argument contains an
  50. -- improper list. It should hold that
  51. toWellFormed :: SExpr atom -> Maybe (WellFormedSExpr atom)
  52. toWellFormed (SAtom a) = Just (WFSAtom a)
  53. toWellFormed (SCons x xs) = do
  54. x' <- toWellFormed x
  55. go xs [x']
  56. where go (SAtom a) rs = Nothing
  57. go SNil rs = Just (WFSList rs)
  58. go (SCons x xs) rs = do
  59. x' <- toWellFormed x
  60. go xs (x':rs)
  61. -- | Convert a WellFormedSExpr back into a SExpr.
  62. fromWellFormed :: WellFormedSExpr atom -> SExpr atom
  63. fromWellFormed (WFSAtom a) = SAtom a
  64. fromWellFormed (WFSList xs) =
  65. foldr SCons SNil (map fromWellFormed xs)