digestive-functors-0.6.1.0: src/Text/Digestive/Form/List.hs
--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
-- | Functionality related to index storage and the DefaultList type.
module Text.Digestive.Form.List
( indicesRef
, parseIndices
, unparseIndices
, DefaultList (..)
, defaultListIndex
) where
--------------------------------------------------------------------------------
import Control.Applicative ((<$>), (<*>))
import Data.Foldable (Foldable (..))
import Data.Maybe (mapMaybe)
import Data.Text (Text)
import qualified Data.Text as T
import Data.Traversable (Traversable (..))
import Prelude hiding (foldr)
--------------------------------------------------------------------------------
import Text.Digestive.Util
--------------------------------------------------------------------------------
-- | Key used to store list indices
indicesRef :: Text
indicesRef = "indices"
--------------------------------------------------------------------------------
-- | Parse a string of comma-delimited integers to a list.
-- Unparseable substrings are left out of the result.
parseIndices :: Text -> [Int]
parseIndices = mapMaybe (readMaybe . T.unpack) . T.split (== ',')
--------------------------------------------------------------------------------
-- | Serialize a list of integers as a comma-delimited Text
unparseIndices :: [Int] -> Text
unparseIndices = T.intercalate "," . map (T.pack . show)
--------------------------------------------------------------------------------
-- | A list which, when indexed on non-existant positions, returns a default
-- value.
data DefaultList a = DefaultList a [a]
--------------------------------------------------------------------------------
instance Functor DefaultList where
fmap f (DefaultList x xs) = DefaultList (f x) (map f xs)
--------------------------------------------------------------------------------
instance Foldable DefaultList where
foldr f z (DefaultList x xs) = f x (foldr f z xs)
--------------------------------------------------------------------------------
instance Traversable DefaultList where
traverse f (DefaultList x xs) = DefaultList <$> f x <*> traverse f xs
--------------------------------------------------------------------------------
-- | Safe indexing of a DefaultList - returns the default value if
-- the given index is out of bounds.
defaultListIndex :: DefaultList a -> Int -> a
defaultListIndex (DefaultList x xs) i
| i < 0 = x
| otherwise = case drop i xs of
(y : _) -> y
[] -> x