WellFormed.hs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. {-# LANGUAGE PatternSynonyms #-}
  2. module Data.SCargot.Repr.WellFormed
  3. ( -- * 'WellFormedSExpr' representation
  4. R.WellFormedSExpr(..)
  5. , R.toWellFormed
  6. , R.fromWellFormed
  7. -- * Useful pattern synonyms
  8. , pattern (:::)
  9. , pattern L
  10. , pattern A
  11. , pattern Nil
  12. -- * Useful processing functions
  13. , fromPair
  14. , fromList
  15. , fromAtom
  16. , asPair
  17. , asList
  18. , isAtom
  19. , asAtom
  20. , asAssoc
  21. , car
  22. , cdr
  23. ) where
  24. import Control.Applicative ((<$>), (<*>), pure)
  25. import Data.SCargot.Repr as R
  26. -- | A shorter infix alias to grab the head
  27. -- and tail of a `WFSList`
  28. pattern x ::: xs = R.WFSList (x : xs)
  29. -- | A shorter alias for `WFSList`
  30. pattern L xs = R.WFSList xs
  31. -- | A shorter alias for `WFSAtom`
  32. pattern A a = R.WFSAtom a
  33. -- | A shorter alias for `WFSList []`
  34. pattern Nil = R.WFSList []
  35. type S t = R.WellFormedSExpr t
  36. type Parse t a = R.WellFormedSExpr t -> Either String a
  37. -- | Utility function for parsing a pair of things.
  38. fromPair :: (WellFormedSExpr t -> Either String a)
  39. -> (WellFormedSExpr t -> Either String b)
  40. -> WellFormedSExpr t -> Either String (a, b)
  41. fromPair pl pr (L [l, r]) = (,) <$> pl l <*> pr r
  42. fromPair _ _ sx = Left ("Expected two-element list")
  43. -- | Utility function for parsing a list of things.
  44. fromList :: (WellFormedSExpr t -> Either String a)
  45. -> WellFormedSExpr t -> Either String [a]
  46. fromList p (L ss) = mapM p ss
  47. fromList _ sx = Left ("Expected list")
  48. fromAtom :: WellFormedSExpr t -> Either String t
  49. fromAtom (L _) = Left "Expected atom; found list"
  50. fromAtom (A a) = return a
  51. asPair :: ((WellFormedSExpr t, WellFormedSExpr t) -> Either String a)
  52. -> WellFormedSExpr t -> Either String a
  53. asPair f (L [l, r]) = f (l, r)
  54. asPair _ sx = Left ("Expected two-element list")
  55. asList :: ([WellFormedSExpr t] -> Either String a)
  56. -> WellFormedSExpr t -> Either String a
  57. asList f (L ls) = f ls
  58. asList _ sx = Left ("Expected list")
  59. isAtom :: Eq t => t -> WellFormedSExpr t -> Either String ()
  60. isAtom s (A s')
  61. | s == s' = return ()
  62. | otherwise = Left ".."
  63. isAtom _ _ = Left ".."
  64. asAtom :: (t -> Either String a) -> WellFormedSExpr t -> Either String a
  65. asAtom f (A s) = f s
  66. asAtom _ sx = Left ("Expected atom; got list")
  67. asAssoc :: ([(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a)
  68. -> WellFormedSExpr t -> Either String a
  69. asAssoc f (L ss) = gatherPairs ss >>= f
  70. where gatherPairs (L [a, b] : ss) = (:) <$> pure (a, b) <*> gatherPairs ss
  71. gatherPairs [] = pure []
  72. gatherPairs _ = Left "..."
  73. asAssoc _ sx = Left ("Expected assoc list")
  74. car :: (WellFormedSExpr t -> Either String t')
  75. -> [WellFormedSExpr t] -> Either String t'
  76. car f (x:_) = f x
  77. car _ [] = Left "car: Taking car of zero-element list"
  78. cdr :: ([WellFormedSExpr t] -> Either String t')
  79. -> [WellFormedSExpr t] -> Either String t'
  80. cdr f (_:xs) = f xs
  81. cdr _ [] = Left "cdr: Taking cdr of zero-element list"