{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
module Data.SCargot.Repr.WellFormed
(
R.WellFormedSExpr(..)
, R.toWellFormed
, R.fromWellFormed
, cons
, uncons
, pattern (:::)
, pattern L
, pattern A
, pattern Nil
, fromPair
, fromList
, fromAtom
, asPair
, asList
, isAtom
, isNil
, asAtom
, asAssoc
, car
, cdr
) where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative ((<$>), (<*>), pure)
#endif
import Data.SCargot.Repr as R
uncons :: WellFormedSExpr a -> Maybe (WellFormedSExpr a, WellFormedSExpr a)
uncons :: forall a.
WellFormedSExpr a -> Maybe (WellFormedSExpr a, WellFormedSExpr a)
uncons R.WFSAtom {} = forall a. Maybe a
Nothing
uncons (R.WFSList []) = forall a. Maybe a
Nothing
uncons (R.WFSList (WellFormedSExpr a
x:[WellFormedSExpr a]
xs)) = forall a. a -> Maybe a
Just (WellFormedSExpr a
x, forall atom. [WellFormedSExpr atom] -> WellFormedSExpr atom
R.WFSList [WellFormedSExpr a]
xs)
cons :: WellFormedSExpr a -> WellFormedSExpr a -> Maybe (WellFormedSExpr a)
cons :: forall a.
WellFormedSExpr a -> WellFormedSExpr a -> Maybe (WellFormedSExpr a)
cons WellFormedSExpr a
_ (R.WFSAtom {}) = forall a. Maybe a
Nothing
cons WellFormedSExpr a
x (R.WFSList [WellFormedSExpr a]
xs) = forall a. a -> Maybe a
Just (forall atom. [WellFormedSExpr atom] -> WellFormedSExpr atom
R.WFSList (WellFormedSExpr a
xforall a. a -> [a] -> [a]
:[WellFormedSExpr a]
xs))
#if MIN_VERSION_base(4,8,0)
pattern (:::) :: WellFormedSExpr a -> WellFormedSExpr a -> WellFormedSExpr a
#endif
pattern x $m::: :: forall {r} {a}.
WellFormedSExpr a
-> (WellFormedSExpr a -> WellFormedSExpr a -> r)
-> ((# #) -> r)
-> r
::: xs <- (uncons -> Just (x, xs))
#if MIN_VERSION_base(4,8,0)
pattern L :: [WellFormedSExpr t] -> WellFormedSExpr t
#endif
pattern $bL :: forall atom. [WellFormedSExpr atom] -> WellFormedSExpr atom
$mL :: forall {r} {t}.
WellFormedSExpr t
-> ([WellFormedSExpr t] -> r) -> ((# #) -> r) -> r
L xs = R.WFSList xs
#if MIN_VERSION_base(4,8,0)
pattern A :: t -> WellFormedSExpr t
#endif
pattern $bA :: forall t. t -> WellFormedSExpr t
$mA :: forall {r} {t}. WellFormedSExpr t -> (t -> r) -> ((# #) -> r) -> r
A a = R.WFSAtom a
#if MIN_VERSION_base(4,8,0)
pattern Nil :: WellFormedSExpr t
#endif
pattern $bNil :: forall t. WellFormedSExpr t
$mNil :: forall {r} {t}.
WellFormedSExpr t -> ((# #) -> r) -> ((# #) -> r) -> r
Nil = R.WFSList []
getShape :: WellFormedSExpr a -> String
getShape :: forall a. WellFormedSExpr a -> String
getShape WFSAtom {} = String
"atom"
getShape (WFSList []) = String
"empty list"
getShape (WFSList [WellFormedSExpr a]
sx) = String
"list of length " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [WellFormedSExpr a]
sx)
fromPair :: (WellFormedSExpr t -> Either String a)
-> (WellFormedSExpr t -> Either String b)
-> WellFormedSExpr t -> Either String (a, b)
fromPair :: forall t a b.
(WellFormedSExpr t -> Either String a)
-> (WellFormedSExpr t -> Either String b)
-> WellFormedSExpr t
-> Either String (a, b)
fromPair WellFormedSExpr t -> Either String a
pl WellFormedSExpr t -> Either String b
pr (L [WellFormedSExpr t
l, WellFormedSExpr t
r]) = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WellFormedSExpr t -> Either String a
pl WellFormedSExpr t
l forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> WellFormedSExpr t -> Either String b
pr WellFormedSExpr t
r
fromPair WellFormedSExpr t -> Either String a
_ WellFormedSExpr t -> Either String b
_ WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"fromPair: expected two-element list; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
fromList :: (WellFormedSExpr t -> Either String a)
-> WellFormedSExpr t -> Either String [a]
fromList :: forall t a.
(WellFormedSExpr t -> Either String a)
-> WellFormedSExpr t -> Either String [a]
fromList WellFormedSExpr t -> Either String a
p (L [WellFormedSExpr t]
ss) = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM WellFormedSExpr t -> Either String a
p [WellFormedSExpr t]
ss
fromList WellFormedSExpr t -> Either String a
_ WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"fromList: expected list; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
fromAtom :: WellFormedSExpr t -> Either String t
fromAtom :: forall t. WellFormedSExpr t -> Either String t
fromAtom (A t
a) = forall (m :: * -> *) a. Monad m => a -> m a
return t
a
fromAtom WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"fromAtom: expected atom; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
asPair :: ((WellFormedSExpr t, WellFormedSExpr t) -> Either String a)
-> WellFormedSExpr t -> Either String a
asPair :: forall t a.
((WellFormedSExpr t, WellFormedSExpr t) -> Either String a)
-> WellFormedSExpr t -> Either String a
asPair (WellFormedSExpr t, WellFormedSExpr t) -> Either String a
f (L [WellFormedSExpr t
l, WellFormedSExpr t
r]) = (WellFormedSExpr t, WellFormedSExpr t) -> Either String a
f (WellFormedSExpr t
l, WellFormedSExpr t
r)
asPair (WellFormedSExpr t, WellFormedSExpr t) -> Either String a
_ WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"asPair: expected two-element list; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
asList :: ([WellFormedSExpr t] -> Either String a)
-> WellFormedSExpr t -> Either String a
asList :: forall t a.
([WellFormedSExpr t] -> Either String a)
-> WellFormedSExpr t -> Either String a
asList [WellFormedSExpr t] -> Either String a
f (L [WellFormedSExpr t]
ls) = [WellFormedSExpr t] -> Either String a
f [WellFormedSExpr t]
ls
asList [WellFormedSExpr t] -> Either String a
_ WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"asList: expected list; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
isAtom :: Eq t => t -> WellFormedSExpr t -> Either String ()
isAtom :: forall t. Eq t => t -> WellFormedSExpr t -> Either String ()
isAtom t
s (A t
s')
| t
s forall a. Eq a => a -> a -> Bool
== t
s' = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = forall a b. a -> Either a b
Left String
"isAtom: failed to match atom"
isAtom t
_ WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"isAtom: expected atom; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
isNil :: WellFormedSExpr t -> Either String ()
isNil :: forall t. WellFormedSExpr t -> Either String ()
isNil WellFormedSExpr t
Nil = forall (m :: * -> *) a. Monad m => a -> m a
return ()
isNil WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"isNil: expected nil; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
asAtom :: (t -> Either String a) -> WellFormedSExpr t -> Either String a
asAtom :: forall t a.
(t -> Either String a) -> WellFormedSExpr t -> Either String a
asAtom t -> Either String a
f (A t
s) = t -> Either String a
f t
s
asAtom t -> Either String a
_ WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"asAtom: expected atom; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
asAssoc :: ([(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a)
-> WellFormedSExpr t -> Either String a
asAssoc :: forall t a.
([(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a)
-> WellFormedSExpr t -> Either String a
asAssoc [(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a
f (L [WellFormedSExpr t]
ss) = forall {a}.
[WellFormedSExpr a]
-> Either String [(WellFormedSExpr a, WellFormedSExpr a)]
gatherPairs [WellFormedSExpr t]
ss forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a
f
where gatherPairs :: [WellFormedSExpr a]
-> Either String [(WellFormedSExpr a, WellFormedSExpr a)]
gatherPairs (L [WellFormedSExpr a
a, WellFormedSExpr a
b] : [WellFormedSExpr a]
ts) = (:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure (WellFormedSExpr a
a, WellFormedSExpr a
b) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [WellFormedSExpr a]
-> Either String [(WellFormedSExpr a, WellFormedSExpr a)]
gatherPairs [WellFormedSExpr a]
ts
gatherPairs [] = forall (f :: * -> *) a. Applicative f => a -> f a
pure []
gatherPairs (WellFormedSExpr a
sx:[WellFormedSExpr a]
_) = forall a b. a -> Either a b
Left (String
"asAssoc: expected pair; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr a
sx)
asAssoc [(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a
_ WellFormedSExpr t
sx = forall a b. a -> Either a b
Left (String
"asAssoc: expected list; found " forall a. [a] -> [a] -> [a]
++ forall a. WellFormedSExpr a -> String
getShape WellFormedSExpr t
sx)
car :: (WellFormedSExpr t -> Either String t')
-> [WellFormedSExpr t] -> Either String t'
car :: forall t t'.
(WellFormedSExpr t -> Either String t')
-> [WellFormedSExpr t] -> Either String t'
car WellFormedSExpr t -> Either String t'
f (WellFormedSExpr t
x:[WellFormedSExpr t]
_) = WellFormedSExpr t -> Either String t'
f WellFormedSExpr t
x
car WellFormedSExpr t -> Either String t'
_ [] = forall a b. a -> Either a b
Left String
"car: Taking car of zero-element list"
cdr :: ([WellFormedSExpr t] -> Either String t')
-> [WellFormedSExpr t] -> Either String t'
cdr :: forall t t'.
([WellFormedSExpr t] -> Either String t')
-> [WellFormedSExpr t] -> Either String t'
cdr [WellFormedSExpr t] -> Either String t'
f (WellFormedSExpr t
_:[WellFormedSExpr t]
xs) = [WellFormedSExpr t] -> Either String t'
f [WellFormedSExpr t]
xs
cdr [WellFormedSExpr t] -> Either String t'
_ [] = forall a b. a -> Either a b
Left String
"cdr: Taking cdr of zero-element list"