reprinter-0.3.0.0: src/Text/Reprinter/StringLike.hs
{-# LANGUAGE TypeFamilies #-}
module Text.Reprinter.StringLike
( StringLike(..)
, IsString(..)
) where
import Data.List (uncons)
import Data.String (IsString(..))
import qualified Data.Text as TextStrict
import qualified Data.Text.Lazy as TextLazy
import qualified Data.ByteString.Char8 as BSCStrict
import qualified Data.ByteString.Lazy.Char8 as BSCLazy
-- | Data types that can be used as a list-like structure of 'Char's.
--
-- Clumsy solution to allow parameterising over the input type (Text,
-- ByteString, String), rather than converting to and from an internal concrete
-- type. Only operations required by the reprinting algorithm are included.
-- Where possible, operations are prefilled using presumed-existing instances
-- (any @[Char]@-like should be a monoid and have a @String -> a@).
class (Monoid a, IsString a) => StringLike a where
slCons :: Char -> a -> a
slUncons :: a -> Maybe (Char, a)
slNull :: a -> Bool
slReverse :: a -> a
-- | like @unpack@
slToString :: a -> String
-- same trick as used in IsString, to avoid possible ambiguity issues
instance (a ~ Char) => StringLike [a] where
slCons = (:)
slUncons = uncons
slNull = null
slReverse = reverse
slToString = id
instance StringLike TextStrict.Text where
slCons = TextStrict.cons
slUncons = TextStrict.uncons
slNull = TextStrict.null
slReverse = TextStrict.reverse
slToString = TextStrict.unpack
instance StringLike TextLazy.Text where
slCons = TextLazy.cons
slUncons = TextLazy.uncons
slNull = TextLazy.null
slReverse = TextLazy.reverse
slToString = TextLazy.unpack
instance StringLike BSCStrict.ByteString where
slCons = BSCStrict.cons
slUncons = BSCStrict.uncons
slNull = BSCStrict.null
slReverse = BSCStrict.reverse
slToString = BSCStrict.unpack
instance StringLike BSCLazy.ByteString where
slCons = BSCLazy.cons
slUncons = BSCLazy.uncons
slNull = BSCLazy.null
slReverse = BSCLazy.reverse
slToString = BSCLazy.unpack