packages feed

bookhound-0.1.0.0: src/Parsers/Collections.hs

{-# LANGUAGE PostfixOperators #-}

module Parsers.Collections where

import Parser (Parser)
import ParserCombinators (IsMatch(..), (<|>), (|*), (|?), maybeWithin)
import Parsers.Char (colon, comma, openSquare, closeSquare,
                     openParens, closeParens, openCurly, closeCurly)
import Parsers.String(spacing)

import qualified Data.Foldable as Foldable
import qualified Data.Map as Map
import Data.Map(Map)


collOf :: Parser a -> Parser b -> Parser c -> Parser d -> Parser [d]
collOf sep start end elemParser = do start
                                     elems <- ((maybeWithin spacing $ elemParser <* sep) |*)
                                     elem  <- maybeWithin spacing (elemParser |?)
                                     end
                                     pure (elems ++ Foldable.toList elem)


listOf :: Parser a -> Parser [a]
listOf = collOf comma openSquare closeSquare

tupleOf :: Parser a -> Parser [a]
tupleOf = collOf comma openParens closeParens

mapOf :: Ord b => Parser a -> Parser b -> Parser c -> Parser (Map b c)
mapOf sep p1 p2 = Map.fromList <$> collOf comma openCurly closeCurly
                               (mapEntryOf p1 p2)  where

  mapEntryOf p1 p2 = do key <- p1
                        maybeWithin spacing sep
                        value <- p2
                        pure (key, value)