-- |
-- Module      :  Data.SExpresso.SExpr
-- Copyright   :  © 2019 Vincent Archambault
-- License     :  0BSD
--
-- Maintainer  :  Vincent Archambault <archambault.v@gmail.com>
-- Stability   :  experimental
--
-- Definition of S-expression

{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, DeriveDataTypeable #-}


module Data.SExpresso.SExpr
  (
    SExpr(..),
    Sexp,
    pattern A,
    pattern L,
    pattern Sexp,
    pattern (:::),
    pattern Nil,
    isAtom,
    sAtom,
    isList,
    sList
  )
  where

import Data.Bifunctor.TH
import Data.Data
import Data.Functor.Foldable.TH

-- | The datatype 'SExpr' is the definition of an S-expression for the
-- library S-expresso.
--
-- The parameter @a@ allows you to specify the datatype of atoms and
-- the parameter @b@ is usefull for keeping metadata about S-expression
-- like source position for example.
data SExpr b a = SList b [SExpr b a]
               | SAtom a
               deriving (SExpr b a -> SExpr b a -> Bool
(SExpr b a -> SExpr b a -> Bool)
-> (SExpr b a -> SExpr b a -> Bool) -> Eq (SExpr b a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall b a. (Eq b, Eq a) => SExpr b a -> SExpr b a -> Bool
/= :: SExpr b a -> SExpr b a -> Bool
$c/= :: forall b a. (Eq b, Eq a) => SExpr b a -> SExpr b a -> Bool
== :: SExpr b a -> SExpr b a -> Bool
$c== :: forall b a. (Eq b, Eq a) => SExpr b a -> SExpr b a -> Bool
Eq, Int -> SExpr b a -> ShowS
[SExpr b a] -> ShowS
SExpr b a -> String
(Int -> SExpr b a -> ShowS)
-> (SExpr b a -> String)
-> ([SExpr b a] -> ShowS)
-> Show (SExpr b a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall b a. (Show b, Show a) => Int -> SExpr b a -> ShowS
forall b a. (Show b, Show a) => [SExpr b a] -> ShowS
forall b a. (Show b, Show a) => SExpr b a -> String
showList :: [SExpr b a] -> ShowS
$cshowList :: forall b a. (Show b, Show a) => [SExpr b a] -> ShowS
show :: SExpr b a -> String
$cshow :: forall b a. (Show b, Show a) => SExpr b a -> String
showsPrec :: Int -> SExpr b a -> ShowS
$cshowsPrec :: forall b a. (Show b, Show a) => Int -> SExpr b a -> ShowS
Show, a -> SExpr b b -> SExpr b a
(a -> b) -> SExpr b a -> SExpr b b
(forall a b. (a -> b) -> SExpr b a -> SExpr b b)
-> (forall a b. a -> SExpr b b -> SExpr b a) -> Functor (SExpr b)
forall a b. a -> SExpr b b -> SExpr b a
forall a b. (a -> b) -> SExpr b a -> SExpr b b
forall b a b. a -> SExpr b b -> SExpr b a
forall b a b. (a -> b) -> SExpr b a -> SExpr b b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SExpr b b -> SExpr b a
$c<$ :: forall b a b. a -> SExpr b b -> SExpr b a
fmap :: (a -> b) -> SExpr b a -> SExpr b b
$cfmap :: forall b a b. (a -> b) -> SExpr b a -> SExpr b b
Functor, Functor (SExpr b)
Foldable (SExpr b)
Functor (SExpr b)
-> Foldable (SExpr b)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> SExpr b a -> f (SExpr b b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    SExpr b (f a) -> f (SExpr b a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> SExpr b a -> m (SExpr b b))
-> (forall (m :: * -> *) a.
    Monad m =>
    SExpr b (m a) -> m (SExpr b a))
-> Traversable (SExpr b)
(a -> f b) -> SExpr b a -> f (SExpr b b)
forall b. Functor (SExpr b)
forall b. Foldable (SExpr b)
forall b (m :: * -> *) a. Monad m => SExpr b (m a) -> m (SExpr b a)
forall b (f :: * -> *) a.
Applicative f =>
SExpr b (f a) -> f (SExpr b a)
forall b (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SExpr b a -> m (SExpr b b)
forall b (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SExpr b a -> f (SExpr b b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => SExpr b (m a) -> m (SExpr b a)
forall (f :: * -> *) a.
Applicative f =>
SExpr b (f a) -> f (SExpr b a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SExpr b a -> m (SExpr b b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SExpr b a -> f (SExpr b b)
sequence :: SExpr b (m a) -> m (SExpr b a)
$csequence :: forall b (m :: * -> *) a. Monad m => SExpr b (m a) -> m (SExpr b a)
mapM :: (a -> m b) -> SExpr b a -> m (SExpr b b)
$cmapM :: forall b (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SExpr b a -> m (SExpr b b)
sequenceA :: SExpr b (f a) -> f (SExpr b a)
$csequenceA :: forall b (f :: * -> *) a.
Applicative f =>
SExpr b (f a) -> f (SExpr b a)
traverse :: (a -> f b) -> SExpr b a -> f (SExpr b b)
$ctraverse :: forall b (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SExpr b a -> f (SExpr b b)
$cp2Traversable :: forall b. Foldable (SExpr b)
$cp1Traversable :: forall b. Functor (SExpr b)
Traversable, SExpr b a -> Bool
(a -> m) -> SExpr b a -> m
(a -> b -> b) -> b -> SExpr b a -> b
(forall m. Monoid m => SExpr b m -> m)
-> (forall m a. Monoid m => (a -> m) -> SExpr b a -> m)
-> (forall m a. Monoid m => (a -> m) -> SExpr b a -> m)
-> (forall a b. (a -> b -> b) -> b -> SExpr b a -> b)
-> (forall a b. (a -> b -> b) -> b -> SExpr b a -> b)
-> (forall b a. (b -> a -> b) -> b -> SExpr b a -> b)
-> (forall b a. (b -> a -> b) -> b -> SExpr b a -> b)
-> (forall a. (a -> a -> a) -> SExpr b a -> a)
-> (forall a. (a -> a -> a) -> SExpr b a -> a)
-> (forall a. SExpr b a -> [a])
-> (forall a. SExpr b a -> Bool)
-> (forall a. SExpr b a -> Int)
-> (forall a. Eq a => a -> SExpr b a -> Bool)
-> (forall a. Ord a => SExpr b a -> a)
-> (forall a. Ord a => SExpr b a -> a)
-> (forall a. Num a => SExpr b a -> a)
-> (forall a. Num a => SExpr b a -> a)
-> Foldable (SExpr b)
forall a. Eq a => a -> SExpr b a -> Bool
forall a. Num a => SExpr b a -> a
forall a. Ord a => SExpr b a -> a
forall m. Monoid m => SExpr b m -> m
forall a. SExpr b a -> Bool
forall a. SExpr b a -> Int
forall a. SExpr b a -> [a]
forall a. (a -> a -> a) -> SExpr b a -> a
forall b a. Eq a => a -> SExpr b a -> Bool
forall b a. Num a => SExpr b a -> a
forall b a. Ord a => SExpr b a -> a
forall m a. Monoid m => (a -> m) -> SExpr b a -> m
forall b m. Monoid m => SExpr b m -> m
forall b a. SExpr b a -> Bool
forall b a. SExpr b a -> Int
forall b a. SExpr b a -> [a]
forall b a. (b -> a -> b) -> b -> SExpr b a -> b
forall a b. (a -> b -> b) -> b -> SExpr b a -> b
forall b a. (a -> a -> a) -> SExpr b a -> a
forall b m a. Monoid m => (a -> m) -> SExpr b a -> m
forall b b a. (b -> a -> b) -> b -> SExpr b a -> b
forall b a b. (a -> b -> b) -> b -> SExpr b a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: SExpr b a -> a
$cproduct :: forall b a. Num a => SExpr b a -> a
sum :: SExpr b a -> a
$csum :: forall b a. Num a => SExpr b a -> a
minimum :: SExpr b a -> a
$cminimum :: forall b a. Ord a => SExpr b a -> a
maximum :: SExpr b a -> a
$cmaximum :: forall b a. Ord a => SExpr b a -> a
elem :: a -> SExpr b a -> Bool
$celem :: forall b a. Eq a => a -> SExpr b a -> Bool
length :: SExpr b a -> Int
$clength :: forall b a. SExpr b a -> Int
null :: SExpr b a -> Bool
$cnull :: forall b a. SExpr b a -> Bool
toList :: SExpr b a -> [a]
$ctoList :: forall b a. SExpr b a -> [a]
foldl1 :: (a -> a -> a) -> SExpr b a -> a
$cfoldl1 :: forall b a. (a -> a -> a) -> SExpr b a -> a
foldr1 :: (a -> a -> a) -> SExpr b a -> a
$cfoldr1 :: forall b a. (a -> a -> a) -> SExpr b a -> a
foldl' :: (b -> a -> b) -> b -> SExpr b a -> b
$cfoldl' :: forall b b a. (b -> a -> b) -> b -> SExpr b a -> b
foldl :: (b -> a -> b) -> b -> SExpr b a -> b
$cfoldl :: forall b b a. (b -> a -> b) -> b -> SExpr b a -> b
foldr' :: (a -> b -> b) -> b -> SExpr b a -> b
$cfoldr' :: forall b a b. (a -> b -> b) -> b -> SExpr b a -> b
foldr :: (a -> b -> b) -> b -> SExpr b a -> b
$cfoldr :: forall b a b. (a -> b -> b) -> b -> SExpr b a -> b
foldMap' :: (a -> m) -> SExpr b a -> m
$cfoldMap' :: forall b m a. Monoid m => (a -> m) -> SExpr b a -> m
foldMap :: (a -> m) -> SExpr b a -> m
$cfoldMap :: forall b m a. Monoid m => (a -> m) -> SExpr b a -> m
fold :: SExpr b m -> m
$cfold :: forall b m. Monoid m => SExpr b m -> m
Foldable, Typeable (SExpr b a)
DataType
Constr
Typeable (SExpr b a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> SExpr b a -> c (SExpr b a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (SExpr b a))
-> (SExpr b a -> Constr)
-> (SExpr b a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (SExpr b a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (SExpr b a)))
-> ((forall b. Data b => b -> b) -> SExpr b a -> SExpr b a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SExpr b a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SExpr b a -> r)
-> (forall u. (forall d. Data d => d -> u) -> SExpr b a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> SExpr b a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a))
-> Data (SExpr b a)
SExpr b a -> DataType
SExpr b a -> Constr
(forall b. Data b => b -> b) -> SExpr b a -> SExpr b a
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SExpr b a -> c (SExpr b a)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SExpr b a)
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SExpr b a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SExpr b a -> u
forall u. (forall d. Data d => d -> u) -> SExpr b a -> [u]
forall b a. (Data b, Data a) => Typeable (SExpr b a)
forall b a. (Data b, Data a) => SExpr b a -> DataType
forall b a. (Data b, Data a) => SExpr b a -> Constr
forall b a.
(Data b, Data a) =>
(forall b. Data b => b -> b) -> SExpr b a -> SExpr b a
forall b a u.
(Data b, Data a) =>
Int -> (forall d. Data d => d -> u) -> SExpr b a -> u
forall b a u.
(Data b, Data a) =>
(forall d. Data d => d -> u) -> SExpr b a -> [u]
forall b a r r'.
(Data b, Data a) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
forall b a r r'.
(Data b, Data a) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
forall b a (m :: * -> *).
(Data b, Data a, Monad m) =>
(forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
forall b a (m :: * -> *).
(Data b, Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
forall b a (c :: * -> *).
(Data b, Data a) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SExpr b a)
forall b a (c :: * -> *).
(Data b, Data a) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SExpr b a -> c (SExpr b a)
forall b a (t :: * -> *) (c :: * -> *).
(Data b, Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (SExpr b a))
forall b a (t :: * -> * -> *) (c :: * -> *).
(Data b, Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SExpr b a))
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SExpr b a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SExpr b a -> c (SExpr b a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (SExpr b a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SExpr b a))
$cSAtom :: Constr
$cSList :: Constr
$tSExpr :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
$cgmapMo :: forall b a (m :: * -> *).
(Data b, Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
gmapMp :: (forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
$cgmapMp :: forall b a (m :: * -> *).
(Data b, Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
gmapM :: (forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
$cgmapM :: forall b a (m :: * -> *).
(Data b, Data a, Monad m) =>
(forall d. Data d => d -> m d) -> SExpr b a -> m (SExpr b a)
gmapQi :: Int -> (forall d. Data d => d -> u) -> SExpr b a -> u
$cgmapQi :: forall b a u.
(Data b, Data a) =>
Int -> (forall d. Data d => d -> u) -> SExpr b a -> u
gmapQ :: (forall d. Data d => d -> u) -> SExpr b a -> [u]
$cgmapQ :: forall b a u.
(Data b, Data a) =>
(forall d. Data d => d -> u) -> SExpr b a -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
$cgmapQr :: forall b a r r'.
(Data b, Data a) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
$cgmapQl :: forall b a r r'.
(Data b, Data a) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SExpr b a -> r
gmapT :: (forall b. Data b => b -> b) -> SExpr b a -> SExpr b a
$cgmapT :: forall b a.
(Data b, Data a) =>
(forall b. Data b => b -> b) -> SExpr b a -> SExpr b a
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SExpr b a))
$cdataCast2 :: forall b a (t :: * -> * -> *) (c :: * -> *).
(Data b, Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SExpr b a))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (SExpr b a))
$cdataCast1 :: forall b a (t :: * -> *) (c :: * -> *).
(Data b, Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (SExpr b a))
dataTypeOf :: SExpr b a -> DataType
$cdataTypeOf :: forall b a. (Data b, Data a) => SExpr b a -> DataType
toConstr :: SExpr b a -> Constr
$ctoConstr :: forall b a. (Data b, Data a) => SExpr b a -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SExpr b a)
$cgunfold :: forall b a (c :: * -> *).
(Data b, Data a) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SExpr b a)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SExpr b a -> c (SExpr b a)
$cgfoldl :: forall b a (c :: * -> *).
(Data b, Data a) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SExpr b a -> c (SExpr b a)
$cp1Data :: forall b a. (Data b, Data a) => Typeable (SExpr b a)
Data)

$(deriveBifunctor ''SExpr)
$(deriveBifoldable ''SExpr)
$(deriveBitraversable ''SExpr)
$(makeBaseFunctor ''SExpr)

-- | The type synonym 'Sexp' is a variant of the more general 'SExpr'
-- datatype with no data for the 'SList' constructor.
type Sexp a = SExpr () a

-- | Bidirectional pattern synonym for the type synonym 'Sexp'. See
-- also the 'L' pattern synonym.
--
-- >foo (Sexp x) = x -- Equivalent to foo (SList () x) = x
-- >s = Sexp []      -- Equivalent to s = SList () []
pattern Sexp :: [Sexp a] -> Sexp a
pattern $bSexp :: [Sexp a] -> Sexp a
$mSexp :: forall r a. Sexp a -> ([Sexp a] -> r) -> (Void# -> r) -> r
Sexp xs = SList () xs

-- | Pattern for matching only the sublist of the 'SList' constructor.
-- See also the Sexp pattern synonym.
--
-- >foo (L xs) = xs -- Equivalent to foo (SList _ xs) = xs
pattern L :: [SExpr b a] -> SExpr b a
pattern $mL :: forall r b a. SExpr b a -> ([SExpr b a] -> r) -> (Void# -> r) -> r
L xs <- SList _ xs

-- | Shorthand for 'SAtom'.
--
-- >foo (A x) = x -- Equivalent to foo (SAtom x) = x
-- > a = A 3      -- Equivalent to a = SAtom 3
pattern A :: a -> SExpr b a
pattern $bA :: a -> SExpr b a
$mA :: forall r a b. SExpr b a -> (a -> r) -> (Void# -> r) -> r
A x = SAtom x

uncons :: SExpr b a -> Maybe (SExpr b a, SExpr b a)
uncons :: SExpr b a -> Maybe (SExpr b a, SExpr b a)
uncons (SAtom a
_) = Maybe (SExpr b a, SExpr b a)
forall a. Maybe a
Nothing
uncons (SList b
_ []) = Maybe (SExpr b a, SExpr b a)
forall a. Maybe a
Nothing
uncons (SList b
b (SExpr b a
x:[SExpr b a]
xs)) = (SExpr b a, SExpr b a) -> Maybe (SExpr b a, SExpr b a)
forall a. a -> Maybe a
Just (SExpr b a
x, b -> [SExpr b a] -> SExpr b a
forall b a. b -> [SExpr b a] -> SExpr b a
SList b
b [SExpr b a]
xs)

-- | Pattern specifying the shape of the sublist of the 'SList' constructor.
-- See also 'Nil'.
--
-- Although it aims to mimic the behavior of the cons (:) constructor
-- for list, this pattern behavior is a little bit different. Indeed
-- its signature is @SExpr b a -> SExpr b a -> SExpr b a@ while the
-- cons (:) constructor signature is @a -> [a] -> [a]@. The first
-- argument type is different in the case of the cons constructor but all
-- the types are identical for the pattern `:::`.
--
-- This implies that the following code
--
-- >foo (x ::: xs) = ...
-- is equivalent to
--
-- >foo (SList b (x : rest)) = let xs = SList b rest
-- >                           in ...
-- If you wish for the @xs@ above to match the remaining of the list,
-- you need to use the 'L' pattern
--
-- >foo (A x ::: L xs)
-- which is equivalent to
-- 
-- >foo (SList b (x : rest)) = let (SList _ xs) = SList b rest
-- >                           in ...
--
-- Other examples :
--
-- >foo (A x1 ::: A x2 ::: Nil)   -- Equivalent to foo (SList _ [SAtom x1, SAtom x2])
-- >foo (L ys ::: A x ::: L xs)   -- Equivalent to foo (SList _ (SList _ ys : SAtom x : xs))
infixr 5 :::
pattern (:::) :: SExpr b a -> SExpr b a -> SExpr b a
pattern x $m::: :: forall r b a.
SExpr b a -> (SExpr b a -> SExpr b a -> r) -> (Void# -> r) -> r
::: xs <- (uncons -> Just (x, xs))

-- | Pattern to mark the end of the list when using the pattern synonym ':::'
pattern Nil :: SExpr b a
pattern $mNil :: forall r b a. SExpr b a -> (Void# -> r) -> (Void# -> r) -> r
Nil <- SList _ []

-- | The 'isAtom' function returns 'True' iff its argument is of the
-- form @SAtom _@.
isAtom :: SExpr b a -> Bool
isAtom :: SExpr b a -> Bool
isAtom (A a
_) = Bool
True
isAtom SExpr b a
_ = Bool
False

-- | The 'sAtom' function returns 'Nothing' if its argument is of the
-- form @SList _ _@ and @'Just' a@ if its argument is of the form @SAtom _@..
sAtom :: SExpr b a -> Maybe a
sAtom :: SExpr b a -> Maybe a
sAtom (A a
x) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
sAtom SExpr b a
_ = Maybe a
forall a. Maybe a
Nothing

-- | The 'isList' function returns 'True' iff its argument is of the
-- form @SList _ _@.
isList :: SExpr b a -> Bool
isList :: SExpr b a -> Bool
isList (L [SExpr b a]
_) = Bool
True
isList SExpr b a
_ = Bool
False

-- | The 'sList' function returns 'Nothing' if its argument is of the
-- form @SAtom _@ and the sublist @xs@ if its argument is of the form
-- @SList _ xs@.
sList :: SExpr b a -> Maybe [SExpr b a]
sList :: SExpr b a -> Maybe [SExpr b a]
sList (L [SExpr b a]
l) = [SExpr b a] -> Maybe [SExpr b a]
forall a. a -> Maybe a
Just [SExpr b a]
l
sList SExpr b a
_ = Maybe [SExpr b a]
forall a. Maybe a
Nothing