Safe Haskell | None |
---|---|
Language | Haskell2010 |
- data SExpr atom
- data RichSExpr atom
- toRich :: SExpr atom -> RichSExpr atom
- fromRich :: RichSExpr atom -> SExpr atom
- data WellFormedSExpr atom
- = WFSList [WellFormedSExpr atom]
- | WFSAtom atom
- toWellFormed :: SExpr atom -> Either String (WellFormedSExpr atom)
- fromWellFormed :: WellFormedSExpr atom -> SExpr atom
Documentation
This module contains several different representations for
s-expressions. The s-cargot library underlying uses the
SExpr
type as its representation type, which is a binary
tree representation with an arbitrary type for its leaves.
This type is not always convenient to manipulate in Haskell code, this module defines two alternate representations which turn a sequence of nested right-branching cons pairs into Haskell lists: that is to say, they transform between
SCons a (SCons b (SCons c SNil)) <=> RSList [a, b, c]
These two types differ in how they handle non-well-formed
lists, i.e. lists that end with an atom. The RichSExpr
format handles this with a special constructor for lists
that end in an atom:
SCons a (SCons b (SAtom c)) <=> RSDotted [a, b] c
On the other hand, the WellFormedSExpr
type elects
not to handle this case. This is unusual for Lisp source code,
but is a reasonable choice for configuration or data
storage formats that use s-expressions, where
non-well-formed lists would be an unnecessary
complication.
To make working with these types less verbose, there are other modules that export pattern aliases and helper functions: these can be found at Data.SCargot.Repr.Basic, Data.SCargot.Repr.Rich, and Data.SCargot.Repr.WellFormed.
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
.
Functor SExpr Source # | |
Foldable SExpr Source # | |
Traversable SExpr Source # | |
IsList (SExpr atom) Source # | |
Eq atom => Eq (SExpr atom) Source # | |
Data atom => Data (SExpr atom) Source # | |
Read atom => Read (SExpr atom) Source # | |
Show atom => Show (SExpr atom) Source # | |
IsString atom => IsString (SExpr atom) Source # | |
type Item (SExpr atom) Source # | |
Rich SExpr representation
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)
. This representation is based on
the structure of the parsed S-Expression, and not on
how it was originally represented: thus, (a . (b))
is going to
be represented as RSList[RSAtom a, RSAtom b]
despite having been originally represented as a
dotted list.
Functor RichSExpr Source # | |
Foldable RichSExpr Source # | |
Traversable RichSExpr Source # | |
IsList (RichSExpr atom) Source # | |
Eq atom => Eq (RichSExpr atom) Source # | |
Data atom => Data (RichSExpr atom) Source # | |
Read atom => Read (RichSExpr atom) Source # | |
Show atom => Show (RichSExpr atom) Source # | |
IsString atom => IsString (RichSExpr atom) Source # | |
type Item (RichSExpr atom) Source # | |
toRich :: SExpr atom -> RichSExpr atom Source #
It should always be true that
fromRich (toRich x) == x
and that
toRich (fromRich x) == x
Well-Formed SExpr representation
data WellFormedSExpr atom Source #
A well-formed s-expression is one which does not
contain any dotted lists. This means that not
every value of SExpr a
can be converted to a
WellFormedSExpr a
, although the opposite is
fine.
WFSList [WellFormedSExpr atom] | |
WFSAtom atom |
Functor WellFormedSExpr Source # | |
Foldable WellFormedSExpr Source # | |
Traversable WellFormedSExpr Source # | |
IsList (WellFormedSExpr atom) Source # | |
Eq atom => Eq (WellFormedSExpr atom) Source # | |
Data atom => Data (WellFormedSExpr atom) Source # | |
Read atom => Read (WellFormedSExpr atom) Source # | |
Show atom => Show (WellFormedSExpr atom) Source # | |
IsString atom => IsString (WellFormedSExpr atom) Source # | |
type Item (WellFormedSExpr atom) Source # | |
toWellFormed :: SExpr atom -> Either String (WellFormedSExpr atom) Source #
This will be Nothing
if the argument contains an
improper list. It should hold that
toWellFormed (fromWellFormed x) == Right x
and also (more tediously) that
case toWellFormed x of Left _ -> True Right y -> x == fromWellFormed y
fromWellFormed :: WellFormedSExpr atom -> SExpr atom Source #
Convert a WellFormedSExpr back into a SExpr.