module Bookhound.Parsers.Collections (collOf, listOf, tupleOf, mapOf) where import Bookhound.Parser (Parser, withError) import Bookhound.ParserCombinators (anySepBy, maybeWithin, satisfies) import Bookhound.Parsers.Char (closeCurly, closeParens, closeSquare, comma, openCurly, openParens, openSquare) import Bookhound.Parsers.String (spacing) import Data.Map (Map) import qualified Data.Map as Map collOf :: Parser a -> Parser b -> Parser c -> Parser d -> Parser [d] collOf :: Parser a -> Parser b -> Parser c -> Parser d -> Parser [d] collOf Parser a start Parser b end Parser c sep Parser d elemParser = String -> Parser [d] -> Parser [d] forall a. String -> Parser a -> Parser a withError String "Collection" (Parser [d] -> Parser [d]) -> Parser [d] -> Parser [d] forall a b. (a -> b) -> a -> b $ Parser a start Parser a -> Parser [d] -> Parser [d] forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> Parser [d] elemsParser Parser [d] -> Parser b -> Parser [d] forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a <* Parser b end where elemsParser :: Parser [d] elemsParser = Parser c -> Parser d -> Parser [d] forall a b. Parser a -> Parser b -> Parser [b] anySepBy Parser c sep (Parser d -> Parser [d]) -> Parser d -> Parser [d] forall a b. (a -> b) -> a -> b $ Parser String -> Parser d -> Parser d forall a b. Parser a -> Parser b -> Parser b maybeWithin Parser String spacing Parser d elemParser listOf :: Parser a -> Parser [a] listOf :: Parser a -> Parser [a] listOf = String -> Parser [a] -> Parser [a] forall a. String -> Parser a -> Parser a withError String "List" (Parser [a] -> Parser [a]) -> (Parser a -> Parser [a]) -> Parser a -> Parser [a] forall b c a. (b -> c) -> (a -> b) -> a -> c . Parser Char -> Parser Char -> Parser Char -> Parser a -> Parser [a] forall a b c d. Parser a -> Parser b -> Parser c -> Parser d -> Parser [d] collOf Parser Char openSquare Parser Char closeSquare Parser Char comma tupleOf :: Parser a -> Parser [a] tupleOf :: Parser a -> Parser [a] tupleOf = String -> Parser [a] -> Parser [a] forall a. String -> Parser a -> Parser a withError String "Tuple" (Parser [a] -> Parser [a]) -> (Parser a -> Parser [a]) -> Parser a -> Parser [a] forall b c a. (b -> c) -> (a -> b) -> a -> c . ([a] -> Bool) -> Parser [a] -> Parser [a] forall a. (a -> Bool) -> Parser a -> Parser a satisfies ((Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >= Int 2) (Int -> Bool) -> ([a] -> Int) -> [a] -> Bool forall b c a. (b -> c) -> (a -> b) -> a -> c . [a] -> Int forall (t :: * -> *) a. Foldable t => t a -> Int length) (Parser [a] -> Parser [a]) -> (Parser a -> Parser [a]) -> Parser a -> Parser [a] forall b c a. (b -> c) -> (a -> b) -> a -> c . Parser Char -> Parser Char -> Parser Char -> Parser a -> Parser [a] forall a b c d. Parser a -> Parser b -> Parser c -> Parser d -> Parser [d] collOf Parser Char openParens Parser Char closeParens Parser Char comma mapOf :: Ord b => Parser a -> Parser b -> Parser c -> Parser (Map b c) mapOf :: Parser a -> Parser b -> Parser c -> Parser (Map b c) mapOf Parser a sep Parser b p1 Parser c p2 = String -> Parser (Map b c) -> Parser (Map b c) forall a. String -> Parser a -> Parser a withError String "Map" (Parser (Map b c) -> Parser (Map b c)) -> Parser (Map b c) -> Parser (Map b c) forall a b. (a -> b) -> a -> b $ [(b, c)] -> Map b c forall k a. Ord k => [(k, a)] -> Map k a Map.fromList ([(b, c)] -> Map b c) -> Parser [(b, c)] -> Parser (Map b c) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Parser Char -> Parser Char -> Parser Char -> Parser (b, c) -> Parser [(b, c)] forall a b c d. Parser a -> Parser b -> Parser c -> Parser d -> Parser [d] collOf Parser Char openCurly Parser Char closeCurly Parser Char comma Parser (b, c) mapEntry where mapEntry :: Parser (b, c) mapEntry = (,) (b -> c -> (b, c)) -> Parser b -> Parser (c -> (b, c)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Parser b p1 Parser (c -> (b, c)) -> Parser a -> Parser (c -> (b, c)) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a <* Parser String -> Parser a -> Parser a forall a b. Parser a -> Parser b -> Parser b maybeWithin Parser String spacing Parser a sep Parser (c -> (b, c)) -> Parser c -> Parser (b, c) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Parser c p2