WellFormed.hs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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 :: Parse t a -> Parse t b -> Parse t (a, b)
  39. fromPair pl pr (L [l, r]) = (,) <$> pl l <*> pr r
  40. fromPair _ _ sx = Left ("Expected two-element list")
  41. -- | Utility function for parsing a list of things.
  42. fromList :: Parse t a -> Parse t [a]
  43. fromList p (L ss) = mapM p ss
  44. fromList _ sx = Left ("Expected list")
  45. fromAtom :: Parse t t
  46. fromAtom (L _) = Left "Expected atom; found list"
  47. fromAtom (A a) = return a
  48. asPair :: ((S t, S t) -> Either String a) -> S t -> Either String a
  49. asPair f (L [l, r]) = f (l, r)
  50. asPair _ sx = Left ("Expected two-element list")
  51. asList :: ([S t] -> Either String a) -> S t -> Either String a
  52. asList f (L ls) = f ls
  53. asList _ sx = Left ("Expected list")
  54. isAtom :: Eq t => t -> S t -> Either String ()
  55. isAtom s (A s')
  56. | s == s' = return ()
  57. | otherwise = Left ".."
  58. isAtom _ _ = Left ".."
  59. asAtom :: Show t => (t -> Either String a) -> S t -> Either String a
  60. asAtom f (A s) = f s
  61. asAtom _ sx = Left ("Expected atom; got" ++ show sx)
  62. asAssoc :: Show t => ([(S t, S t)] -> Either String a) -> S t -> Either String a
  63. asAssoc f (L ss) = gatherPairs ss >>= f
  64. where gatherPairs (L [a, b] : ss) = (:) <$> pure (a, b) <*> gatherPairs ss
  65. gatherPairs [] = pure []
  66. gatherPairs _ = Left "..."
  67. asAssoc _ sx = Left ("Expected assoc list; got " ++ show sx)
  68. car :: (S t -> Either String t') -> [S t] -> Either String t'
  69. car f (x:_) = f x
  70. car _ [] = Left "car: Taking car of zero-element list"
  71. cdr :: ([S t] -> Either String t') -> [S t] -> Either String t'
  72. cdr f (_:xs) = f xs
  73. cdr _ [] = Left "cdr: Taking cdr of zero-element list"