packages feed

sloane-4.0.0: Sloane/Utils.hs

{-# LANGUAGE OverloadedStrings #-}

-- |
-- Copyright   : Anders Claesson 2015
-- Maintainer  : Anders Claesson <anders.claesson@gmail.com>
-- License     : BSD-3
--

module Sloane.Utils
    ( pad
    , parens
    , oneOf
    , chainl1
    , parse_
    ) where

import Data.Monoid
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Char8 (ByteString)
import Data.Attoparsec.ByteString.Char8
import Control.Applicative


-- | @pad d n@ packs the integer @n@ into a `ByteString` padding with
-- \'0\' on the right to achieve length @d@.
--
-- > pad 6 123 = "000123"
--
pad :: Int -> Int -> ByteString
pad d n = B.replicate (d - B.length s) '0' <> s where s = B.pack (show n)

-- | Parse @p@ enclosed in parenthesis.
parens :: Parser a -> Parser a
parens p = string "(" *> p <* string ")"

-- | Parse one of the words in the given `ByteString`.
oneOf :: ByteString -> Parser ByteString
oneOf s = choice (map string (B.words s))

-- | Parse one or more occurrences of @p@, separated by an operator.
-- Returns a value obtained by a left associative application.
chainl1 :: (Monad f, Alternative f) => f a -> f (a -> a -> a) -> f a
chainl1 p op = p >>= rest
  where
    rest a = do { f <- op; b <- p; rest $! f a b } <|> pure a

-- | Run a parser.
parse_ :: Parser t -> ByteString -> Maybe t
parse_ f = either (const Nothing) Just . parseOnly f