{-# LANGUAGE FlexibleInstances #-} -- | An abstaction over string like data types to prevent -- restricting 'Data.Tokenify.tokenizer' to a particular -- data type, as there are many string types in haskell. module Text.Tokenify.CharSeq where import qualified Prelude as Prelude import Prelude hiding (head, tail, null) import qualified GHC.Exts as Exts import qualified Data.Text as Text import Data.Monoid (Monoid) import Data.Text (Text) -- | This typeclass is designed to make the tokenizer more polymorphic, -- which is why it's a super set of both 'Monoid' and 'Eq'. class (Monoid a, Eq a) => CharSeq a where -- | The first char in a 'CharSeq' head :: a -> Maybe Char -- | Every char but the first in a 'CharSeq' tail :: a -> a -- | Pushes the to the head of a 'CharSeq' cons :: Char -> a -> a -- | Pushes the to the end of a 'CharSeq' snoc :: a -> Char -> a -- | A 'CharSeq' containing a single character null :: a -> Bool -- | Makes a 'CharSeq' containing a single character singleton :: Char -> a -- | Provides line information of a 'CharSeq' lineInfo :: a -> [Int] -- | Enables 'Data.Text' to be used for 'Text.Tokenify.tokenizer' instance CharSeq Text where head input | not (Text.null input) = Just (Text.head input) | otherwise = Nothing tail = Text.tail cons = Text.cons snoc = Text.snoc null = Text.null singleton = Text.singleton lineInfo = map Text.length . Text.lines -- | the main purpose of this implemenation is make -- testing in the repl non-painful instance CharSeq [Char] where head input | not (Prelude.null input) = Just (Prelude.head input) | otherwise = Nothing tail = Prelude.tail cons = (:) snoc s c = s ++ [c] null = Prelude.null singleton c = [c] lineInfo = map length . lines