sloane-4.0.0: Sloane/Entry.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
-- |
-- Copyright : Anders Claesson 2015
-- Maintainer : Anders Claesson <anders.claesson@gmail.com>
-- License : BSD-3
--
module Sloane.Entry
( PackedPrg (..)
, PackedEntry (..)
, parsePackedEntry
, parsePackedEntryErr
) where
import GHC.Generics (Generic)
import Data.Maybe
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as B
import qualified Data.Attoparsec.ByteString.Char8 as Ch
import Data.Attoparsec.ByteString.Char8
import Control.Monad
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative
#endif
import Sloane.Utils
import Sloane.OEIS
-- | A compact `ByteString` representation of a `Prg`.
newtype PackedPrg = PPrg ByteString deriving (Eq, Show, Generic)
-- | Similary, a packed entry consists of a packed program together with
-- a packed sequence.
data PackedEntry = PackedEntry
{ getPackedPrg :: PackedPrg
, getPackedSeq :: PackedSeq
} deriving (Eq, Show, Generic)
packedEntry :: Parser PackedEntry
packedEntry =
let f w = if B.last w == '=' then return (PPrg (B.init w)) else mzero
in PackedEntry <$> (Ch.takeWhile1 (/='>') >>= f)
<*> (char '>' *> packedSeq)
-- | A parser for packed entries.
parsePackedEntry :: ByteString -> Maybe PackedEntry
parsePackedEntry = parse_ packedEntry . B.filter (/=' ')
-- | Like `parsePackedEntry` but throws an error rather than returning
-- `Nothing` in case the parse fails.
parsePackedEntryErr :: ByteString -> PackedEntry
parsePackedEntryErr = fromMaybe (error "cannot parse input") . parsePackedEntry