s-cargot-0.1.6.0: A flexible, extensible s-expression library.

Safe Haskell | Safe-Inferred
Language | Haskell2010

Data.SCargot.Repr.WellFormed

Contents

- `WellFormedSExpr` representation
- Constructing and Deconstructing
- Useful pattern synonyms
- Useful processing functions

Synopsis

- data WellFormedSExpr atom
  - = WFSList [WellFormedSExpr atom]
  - | WFSAtom atom
- toWellFormed :: SExpr atom -> Either String (WellFormedSExpr atom)
- fromWellFormed :: WellFormedSExpr atom -> SExpr atom
- cons :: WellFormedSExpr a -> WellFormedSExpr a -> Maybe (WellFormedSExpr a)
- uncons :: WellFormedSExpr a -> Maybe (WellFormedSExpr a, WellFormedSExpr a)
- pattern (:::) :: WellFormedSExpr a -> WellFormedSExpr a -> WellFormedSExpr a
- pattern L :: [WellFormedSExpr t] -> WellFormedSExpr t
- pattern A :: t -> WellFormedSExpr t
- pattern Nil :: WellFormedSExpr t
- fromPair :: (WellFormedSExpr t -> Either String a) -> (WellFormedSExpr t -> Either String b) -> WellFormedSExpr t -> Either String (a, b)
- fromList :: (WellFormedSExpr t -> Either String a) -> WellFormedSExpr t -> Either String [a]
- fromAtom :: WellFormedSExpr t -> Either String t
- asPair :: ((WellFormedSExpr t, WellFormedSExpr t) -> Either String a) -> WellFormedSExpr t -> Either String a
- asList :: ([WellFormedSExpr t] -> Either String a) -> WellFormedSExpr t -> Either String a
- isAtom :: Eq t => t -> WellFormedSExpr t -> Either String ()
- isNil :: WellFormedSExpr t -> Either String ()
- asAtom :: (t -> Either String a) -> WellFormedSExpr t -> Either String a
- asAssoc :: ([(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a) -> WellFormedSExpr t -> Either String a
- car :: (WellFormedSExpr t -> Either String t') -> [WellFormedSExpr t] -> Either String t'
- cdr :: ([WellFormedSExpr t] -> Either String t') -> [WellFormedSExpr t] -> Either String t'

# `WellFormedSExpr` 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.

Constructors

WFSList [WellFormedSExpr atom] |
WFSAtom atom |

#### Instances

Instances details

Foldable WellFormedSExpr Source # |

Instance details

Defined in Data.SCargot.Repr

Methods

fold :: Monoid m => WellFormedSExpr m -> m Source #

foldMap :: Monoid m => (a -> m) -> WellFormedSExpr a -> m Source #

foldMap' :: Monoid m => (a -> m) -> WellFormedSExpr a -> m Source #

foldr :: (a -> b -> b) -> b -> WellFormedSExpr a -> b Source #

foldr' :: (a -> b -> b) -> b -> WellFormedSExpr a -> b Source #

foldl :: (b -> a -> b) -> b -> WellFormedSExpr a -> b Source #

foldl' :: (b -> a -> b) -> b -> WellFormedSExpr a -> b Source #

foldr1 :: (a -> a -> a) -> WellFormedSExpr a -> a Source #

foldl1 :: (a -> a -> a) -> WellFormedSExpr a -> a Source #

toList :: WellFormedSExpr a -> [a] Source #

null :: WellFormedSExpr a -> Bool Source #

length :: WellFormedSExpr a -> Int Source #

elem :: Eq a => a -> WellFormedSExpr a -> Bool Source #

maximum :: Ord a => WellFormedSExpr a -> a Source #

minimum :: Ord a => WellFormedSExpr a -> a Source #

sum :: Num a => WellFormedSExpr a -> a Source #

product :: Num a => WellFormedSExpr a -> a Source #

Traversable WellFormedSExpr Source # |
Instance details Defined in Data.SCargot.Repr Methods traverse :: Applicative f => (a -> f b) -> WellFormedSExpr a -> f (WellFormedSExpr b) Source # sequenceA :: Applicative f => WellFormedSExpr (f a) -> f (WellFormedSExpr a) Source # mapM :: Monad m => (a -> m b) -> WellFormedSExpr a -> m (WellFormedSExpr b) Source # sequence :: Monad m => WellFormedSExpr (m a) -> m (WellFormedSExpr a) Source #
Functor WellFormedSExpr Source # |
Instance details Defined in Data.SCargot.Repr Methods fmap :: (a -> b) -> WellFormedSExpr a -> WellFormedSExpr b Source # (<$) :: a -> WellFormedSExpr b -> WellFormedSExpr a Source #
Data atom => Data (WellFormedSExpr atom) Source # |

Instance details

Defined in Data.SCargot.Repr

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> WellFormedSExpr atom -> c (WellFormedSExpr atom) Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (WellFormedSExpr atom) Source #

toConstr :: WellFormedSExpr atom -> Constr Source #

dataTypeOf :: WellFormedSExpr atom -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (WellFormedSExpr atom)) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (WellFormedSExpr atom)) Source #

gmapT :: (forall b. Data b => b -> b) -> WellFormedSExpr atom -> WellFormedSExpr atom Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> WellFormedSExpr atom -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> WellFormedSExpr atom -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> WellFormedSExpr atom -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> WellFormedSExpr atom -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> WellFormedSExpr atom -> m (WellFormedSExpr atom) Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> WellFormedSExpr atom -> m (WellFormedSExpr atom) Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> WellFormedSExpr atom -> m (WellFormedSExpr atom) Source #

IsString atom => IsString (WellFormedSExpr atom) Source # |
Instance details Defined in Data.SCargot.Repr Methods fromString :: String -> WellFormedSExpr atom Source #
IsList (WellFormedSExpr atom) Source # |
Instance details Defined in Data.SCargot.Repr Associated Types type Item (WellFormedSExpr atom) Source # Methods fromList :: [Item (WellFormedSExpr atom)] -> WellFormedSExpr atom Source # fromListN :: Int -> [Item (WellFormedSExpr atom)] -> WellFormedSExpr atom Source # toList :: WellFormedSExpr atom -> [Item (WellFormedSExpr atom)] Source #
Read atom => Read (WellFormedSExpr atom) Source # |
Instance details Defined in Data.SCargot.Repr Methods readsPrec :: Int -> ReadS (WellFormedSExpr atom) Source # readList :: ReadS [WellFormedSExpr atom] Source # readPrec :: ReadPrec (WellFormedSExpr atom) Source # readListPrec :: ReadPrec [WellFormedSExpr atom] Source #
Show atom => Show (WellFormedSExpr atom) Source # |
Instance details Defined in Data.SCargot.Repr Methods showsPrec :: Int -> WellFormedSExpr atom -> ShowS Source # show :: WellFormedSExpr atom -> String Source # showList :: [WellFormedSExpr atom] -> ShowS Source #
Eq atom => Eq (WellFormedSExpr atom) Source # |
Instance details Defined in Data.SCargot.Repr Methods (==) :: WellFormedSExpr atom -> WellFormedSExpr atom -> Bool Source # (/=) :: WellFormedSExpr atom -> WellFormedSExpr atom -> Bool Source #
type Item (WellFormedSExpr atom) Source # |
Instance details Defined in Data.SCargot.Repr type Item (WellFormedSExpr atom) = WellFormedSExpr atom

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.

# Constructing and Deconstructing

cons :: WellFormedSExpr a -> WellFormedSExpr a -> Maybe (WellFormedSExpr a) Source #

Combine the two-expressions into a new one. This will return `Nothing` if the resulting s-expression is not well-formed.

    >>> cons (A "el") (L [A "eph", A "ant"])
    Just (WFSList [WFSAtom "el",WFSAtom "eph",WFSAtom "ant"])
    >>> cons (A "pachy") (A "derm"))
    Nothing

uncons :: WellFormedSExpr a -> Maybe (WellFormedSExpr a, WellFormedSExpr a) Source #

Produce the head and tail of the s-expression (if possible).

    >>> uncons (L [A "el", A "eph", A "ant"])
    Just (WFSAtom "el",WFSList [WFSAtom "eph",WFSAtom "ant"])

# Useful pattern synonyms

pattern (:::) :: WellFormedSExpr a -> WellFormedSExpr a -> WellFormedSExpr a Source #

A shorter infix alias to grab the head and tail of a `WFSList`. This pattern is unidirectional, because it cannot be guaranteed that it is used to construct well-formed s-expressions; use the function "cons" instead.

    >>> let sum (x ::: xs) = x + sum xs; sum Nil = 0

pattern L :: [WellFormedSExpr t] -> WellFormedSExpr t Source #

A shorter alias for `WFSList`

    >>> L [A "pachy", A "derm"]
    WFSList [WFSAtom "pachy",WFSAtom "derm"]

pattern A :: t -> WellFormedSExpr t Source #

A shorter alias for `WFSAtom`

    >>> A "elephant"
    WFSAtom "elephant"

pattern Nil :: WellFormedSExpr t Source #

A shorter alias for `WFSList` `[]`

    >>> Nil
    WFSList []

# Useful processing functions

fromPair :: (WellFormedSExpr t -> Either String a) -> (WellFormedSExpr t -> Either String b) -> WellFormedSExpr t -> Either String (a, b) Source #

Utility function for parsing a pair of things.

    >>> fromPair (isAtom "pachy") (asAtom return) (L [A "pachy", A "derm"])
    Right ((), "derm")
    >>> fromPair (isAtom "pachy") fromAtom (L [A "pachy"])
    Left "Expected two-element list"

fromList :: (WellFormedSExpr t -> Either String a) -> WellFormedSExpr t -> Either String [a] Source #

Utility function for parsing a list of things.

    >>> fromList fromAtom (L [A "this", A "that", A "the-other"])
    Right ["this","that","the-other"]
    >>> fromList fromAtom (A "pachyderm")
    Left "asList: expected proper list; found dotted list"

fromAtom :: WellFormedSExpr t -> Either String t Source #

Utility function for parsing a single atom

    >>> fromAtom (A "elephant")
    Right "elephant"
    >>> fromAtom (L [A "elephant"])
    Left "fromAtom: expected atom; found list"

asPair :: ((WellFormedSExpr t, WellFormedSExpr t) -> Either String a) -> WellFormedSExpr t -> Either String a Source #

Parses a two-element list using the provided function.

    >>> let go (A l) (A r) = return (l ++ r); go _ _ = Left "expected atoms"
    >>> asPair go (L [A "pachy", A "derm"])
    Right "pachyderm"
    >>> asPair go (L [A "elephant"])
    Left "asPair: expected two-element list; found list of length 1"

asList :: ([WellFormedSExpr t] -> Either String a) -> WellFormedSExpr t -> Either String a Source #

Parse an arbitrary-length list using the provided function.

    >>> let go xs = concat <$> mapM fromAtom xs
    >>> asList go (L [A "el", A "eph", A "ant"])
    Right "elephant"
    >>> asList go (A "pachyderm")
    Left "asList: expected list; found atom"

isAtom :: Eq t => t -> WellFormedSExpr t -> Either String () Source #

Match a given literal atom, failing otherwise.

    >>> isAtom "elephant" (A "elephant")
    Right ()
    >>> isAtom "elephant" (L [A "elephant"])
    Left "isAtom: expected atom; found list"

isNil :: WellFormedSExpr t -> Either String () Source #

Match an empty list, failing otherwise.

    >>> isNil (L [])
    Right ()
    >>> isNil (A "elephant")
    Left "isNil: expected nil; found atom"

asAtom :: (t -> Either String a) -> WellFormedSExpr t -> Either String a Source #

Parse an atom using the provided function.

    >>> import Data.Char (toUpper)
    >>> asAtom (return . map toUpper) (A "elephant")
    Right "ELEPHANT"
    >>> asAtom (return . map toUpper) (L [])
    Left "asAtom: expected atom; found list"

asAssoc :: ([(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a) -> WellFormedSExpr t -> Either String a Source #

Parse an assoc-list using the provided function.

    >>> let def (x, y) = do { a <- fromAtom x; b <- fromAtom y; return (a ++ ": " ++ b) }
    >>> let defList xs = do { defs <- mapM def xs; return (unlines defs) }
    >>> asAssoc defList (L [ L [A "legs", A "four"], L [ A "trunk", A "one"] ])
    Right "legs: four\ntrunk: one\n"
    >>> asAssoc defList (L [ L [A "legs", A "four"], L [ A "elephant"] ])
    Left "asAssoc: expected pair; found list of length 1"

car :: (WellFormedSExpr t -> Either String t') -> [WellFormedSExpr t] -> Either String t' Source #

Run the parser on the first element of a Haskell list of WellFormedSExpr values, failing if the list is empty. This is useful in conjunction with the `asList` function.

cdr :: ([WellFormedSExpr t] -> Either String t') -> [WellFormedSExpr t] -> Either String t' Source #

Run the parser on all but the first element of a Haskell list of WellFormedSExpr values, failing if the list is empty. This is useful in conjunction with the `asList` function.