Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- 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
.
Instances
Foldable SExpr Source # | |
Defined in Data.SCargot.Repr fold :: Monoid m => SExpr m -> m # foldMap :: Monoid m => (a -> m) -> SExpr a -> m # foldMap' :: Monoid m => (a -> m) -> SExpr a -> m # foldr :: (a -> b -> b) -> b -> SExpr a -> b # foldr' :: (a -> b -> b) -> b -> SExpr a -> b # foldl :: (b -> a -> b) -> b -> SExpr a -> b # foldl' :: (b -> a -> b) -> b -> SExpr a -> b # foldr1 :: (a -> a -> a) -> SExpr a -> a # foldl1 :: (a -> a -> a) -> SExpr a -> a # elem :: Eq a => a -> SExpr a -> Bool # maximum :: Ord a => SExpr a -> a # minimum :: Ord a => SExpr a -> a # | |
Traversable SExpr Source # | |
Functor SExpr Source # | |
Data atom => Data (SExpr atom) Source # | |
Defined in Data.SCargot.Repr gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> SExpr atom -> c (SExpr atom) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (SExpr atom) # toConstr :: SExpr atom -> Constr # dataTypeOf :: SExpr atom -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (SExpr atom)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (SExpr atom)) # gmapT :: (forall b. Data b => b -> b) -> SExpr atom -> SExpr atom # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> SExpr atom -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> SExpr atom -> r # gmapQ :: (forall d. Data d => d -> u) -> SExpr atom -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> SExpr atom -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> SExpr atom -> m (SExpr atom) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> SExpr atom -> m (SExpr atom) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> SExpr atom -> m (SExpr atom) # | |
IsString atom => IsString (SExpr atom) Source # | |
Defined in Data.SCargot.Repr fromString :: String -> SExpr atom # | |
IsList (SExpr atom) Source # | |
Read atom => Read (SExpr atom) Source # | |
Show atom => Show (SExpr atom) Source # | |
Eq atom => Eq (SExpr atom) Source # | |
type Item (SExpr atom) Source # | |
Defined in Data.SCargot.Repr |
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.
Instances
Foldable RichSExpr Source # | |
Defined in Data.SCargot.Repr fold :: Monoid m => RichSExpr m -> m # foldMap :: Monoid m => (a -> m) -> RichSExpr a -> m # foldMap' :: Monoid m => (a -> m) -> RichSExpr a -> m # foldr :: (a -> b -> b) -> b -> RichSExpr a -> b # foldr' :: (a -> b -> b) -> b -> RichSExpr a -> b # foldl :: (b -> a -> b) -> b -> RichSExpr a -> b # foldl' :: (b -> a -> b) -> b -> RichSExpr a -> b # foldr1 :: (a -> a -> a) -> RichSExpr a -> a # foldl1 :: (a -> a -> a) -> RichSExpr a -> a # toList :: RichSExpr a -> [a] # length :: RichSExpr a -> Int # elem :: Eq a => a -> RichSExpr a -> Bool # maximum :: Ord a => RichSExpr a -> a # minimum :: Ord a => RichSExpr a -> a # | |
Traversable RichSExpr Source # | |
Functor RichSExpr Source # | |
Data atom => Data (RichSExpr atom) Source # | |
Defined in Data.SCargot.Repr gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> RichSExpr atom -> c (RichSExpr atom) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (RichSExpr atom) # toConstr :: RichSExpr atom -> Constr # dataTypeOf :: RichSExpr atom -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (RichSExpr atom)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (RichSExpr atom)) # gmapT :: (forall b. Data b => b -> b) -> RichSExpr atom -> RichSExpr atom # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> RichSExpr atom -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> RichSExpr atom -> r # gmapQ :: (forall d. Data d => d -> u) -> RichSExpr atom -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> RichSExpr atom -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> RichSExpr atom -> m (RichSExpr atom) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> RichSExpr atom -> m (RichSExpr atom) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> RichSExpr atom -> m (RichSExpr atom) # | |
IsString atom => IsString (RichSExpr atom) Source # | |
Defined in Data.SCargot.Repr fromString :: String -> RichSExpr atom # | |
IsList (RichSExpr atom) Source # | |
Read atom => Read (RichSExpr atom) Source # | |
Show atom => Show (RichSExpr atom) Source # | |
Eq atom => Eq (RichSExpr atom) Source # | |
type Item (RichSExpr atom) Source # | |
Defined in Data.SCargot.Repr |
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 |
Instances
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.