module Data.NonEmptyText
( NonEmptyText
, new
, singleton
, toText
, fromText
, cons
, snoc
, uncons
, unsnoc
, append
, Data.NonEmptyText.head
, Data.NonEmptyText.last
, Data.NonEmptyText.tail
, Data.NonEmptyText.init
, Data.NonEmptyText.length
, isSingleton
) where
import qualified Data.Text as Text
data NonEmptyText = NonEmptyText Char Text.Text
deriving (Eq, Ord)
instance Show NonEmptyText where
show = show . toText
new :: Char -> Text.Text -> NonEmptyText
new = NonEmptyText
singleton :: Char -> NonEmptyText
singleton = flip NonEmptyText Text.empty
isSingleton :: NonEmptyText -> Bool
isSingleton = Text.null . snd . uncons
cons :: Char -> NonEmptyText -> NonEmptyText
cons h t = new h (toText t)
snoc :: NonEmptyText -> Char -> NonEmptyText
snoc (NonEmptyText h t) c = new h (Text.snoc t c)
append :: NonEmptyText -> NonEmptyText -> NonEmptyText
append (NonEmptyText h t) = new h . Text.append t . toText
uncons :: NonEmptyText -> (Char, Text.Text)
uncons (NonEmptyText h t) = (h, t)
unsnoc :: NonEmptyText -> (Text.Text, Char)
unsnoc (NonEmptyText h t) =
case unsnocT t of
Nothing -> (Text.empty, h)
Just (m, e) -> (Text.cons h m, e)
where
unsnocT :: Text.Text -> Maybe (Text.Text, Char)
unsnocT text =
let n = Text.length text 1 in
if Text.null text
then Nothing
else Just (Text.take n text, Text.index text n)
head :: NonEmptyText -> Char
head = fst . uncons
last :: NonEmptyText -> Char
last = snd . unsnoc
tail :: NonEmptyText -> Text.Text
tail = snd . uncons
init :: NonEmptyText -> Text.Text
init = fst . unsnoc
length :: NonEmptyText -> Int
length = (1 +) . Text.length . Data.NonEmptyText.tail
toText :: NonEmptyText -> Text.Text
toText = uncurry Text.cons . uncons
fromText :: Text.Text -> Maybe NonEmptyText
fromText t = Prelude.uncurry NonEmptyText <$> Text.uncons t