{-|
Module      : Obgs.Utils.Read
Description : Utility functions for defining 'Read' instances and parsers.
Copyright   : (c) obgs 2017
License     : MIT
Maintainer  : obgs@protonmail.com
-}
module Obgs.Utils.Read
    (
      -- * Base combinators
      module Text.ParserCombinators.ReadP

      -- * 'Read' instances
    , mkReader

      -- * Additional combinators
    , always
    , intDigit
    ) where

import           Control.Applicative          (liftA2)
import           Data.Char                    (intToDigit)
import           Text.ParserCombinators.ReadP


-- | Shortcut for defining the 'readsPrec' function of a 'Read' instance with
-- just a 'ReadP' parser.
mkReader :: ReadP a -> Int -> ReadS a
mkReader = const . readP_to_S


-- | Parses the given 'String' and returns the given value.
always :: String -> a -> ReadP a
always c x = string c *> pure x


-- | Parses and returns any of the given 'Int' digits.
intDigit :: [Int] -> ReadP Int
intDigit ns = choice $ liftA2 (*>) (char . intToDigit) pure <$> ns
