{- 
    Copyright 2017 Mario Blazevic

    License: BSD3 (see BSD3-LICENSE.txt file)
-}

-- | This module contains orphan 'IsString' and 'TextualMonoid' instances of @Vector Char@.
-- 

{-# LANGUAGE Haskell2010, FlexibleInstances, Trustworthy #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Data.Monoid.Instances.CharVector where

import Data.String (IsString(fromString))
import qualified Data.Vector as Vector

import Data.Monoid.Textual (TextualMonoid(..))

instance IsString (Vector.Vector Char) where
   fromString :: String -> Vector Char
fromString = String -> Vector Char
forall a. [a] -> Vector a
Vector.fromList

instance TextualMonoid (Vector.Vector Char) where
   singleton :: Char -> Vector Char
singleton = Char -> Vector Char
forall a. a -> Vector a
Vector.singleton
   splitCharacterPrefix :: Vector Char -> Maybe (Char, Vector Char)
splitCharacterPrefix Vector Char
t = if Vector Char -> Bool
forall a. Vector a -> Bool
Vector.null Vector Char
t then Maybe (Char, Vector Char)
forall a. Maybe a
Nothing else (Char, Vector Char) -> Maybe (Char, Vector Char)
forall a. a -> Maybe a
Just (Vector Char -> Char
forall a. Vector a -> a
Vector.unsafeHead Vector Char
t, Vector Char -> Vector Char
forall a. Vector a -> Vector a
Vector.unsafeTail Vector Char
t)
   characterPrefix :: Vector Char -> Maybe Char
characterPrefix = (Vector Char -> Int -> Maybe Char
forall a. Vector a -> Int -> Maybe a
Vector.!? Int
0)
   map :: (Char -> Char) -> Vector Char -> Vector Char
map = (Char -> Char) -> Vector Char -> Vector Char
forall a b. (a -> b) -> Vector a -> Vector b
Vector.map
   concatMap :: (Char -> Vector Char) -> Vector Char -> Vector Char
concatMap = (Char -> Vector Char) -> Vector Char -> Vector Char
forall a b. (a -> Vector b) -> Vector a -> Vector b
Vector.concatMap
   toString :: (Vector Char -> String) -> Vector Char -> String
toString = (Vector Char -> String)
-> (Vector Char -> String) -> Vector Char -> String
forall a b. a -> b -> a
const Vector Char -> String
forall a. Vector a -> [a]
Vector.toList
   any :: (Char -> Bool) -> Vector Char -> Bool
any = (Char -> Bool) -> Vector Char -> Bool
forall a. (a -> Bool) -> Vector a -> Bool
Vector.any
   all :: (Char -> Bool) -> Vector Char -> Bool
all = (Char -> Bool) -> Vector Char -> Bool
forall a. (a -> Bool) -> Vector a -> Bool
Vector.all

   foldl :: (a -> Vector Char -> a)
-> (a -> Char -> a) -> a -> Vector Char -> a
foldl   = ((a -> Char -> a) -> a -> Vector Char -> a)
-> (a -> Vector Char -> a)
-> (a -> Char -> a)
-> a
-> Vector Char
-> a
forall a b. a -> b -> a
const (a -> Char -> a) -> a -> Vector Char -> a
forall a b. (a -> b -> a) -> a -> Vector b -> a
Vector.foldl
   foldl' :: (a -> Vector Char -> a)
-> (a -> Char -> a) -> a -> Vector Char -> a
foldl'  = ((a -> Char -> a) -> a -> Vector Char -> a)
-> (a -> Vector Char -> a)
-> (a -> Char -> a)
-> a
-> Vector Char
-> a
forall a b. a -> b -> a
const (a -> Char -> a) -> a -> Vector Char -> a
forall a b. (a -> b -> a) -> a -> Vector b -> a
Vector.foldl'
   foldr :: (Vector Char -> a -> a)
-> (Char -> a -> a) -> a -> Vector Char -> a
foldr   = ((Char -> a -> a) -> a -> Vector Char -> a)
-> (Vector Char -> a -> a)
-> (Char -> a -> a)
-> a
-> Vector Char
-> a
forall a b. a -> b -> a
const (Char -> a -> a) -> a -> Vector Char -> a
forall a b. (a -> b -> b) -> b -> Vector a -> b
Vector.foldr

   scanl :: (Char -> Char -> Char) -> Char -> Vector Char -> Vector Char
scanl = (Char -> Char -> Char) -> Char -> Vector Char -> Vector Char
forall a b. (a -> b -> a) -> a -> Vector b -> Vector a
Vector.scanl
   scanl1 :: (Char -> Char -> Char) -> Vector Char -> Vector Char
scanl1 Char -> Char -> Char
f Vector Char
v | Vector Char -> Bool
forall a. Vector a -> Bool
Vector.null Vector Char
v = Vector Char
forall a. Vector a
Vector.empty
              | Bool
otherwise = (Char -> Char -> Char) -> Vector Char -> Vector Char
forall a. (a -> a -> a) -> Vector a -> Vector a
Vector.scanl1 Char -> Char -> Char
f Vector Char
v
   scanr :: (Char -> Char -> Char) -> Char -> Vector Char -> Vector Char
scanr = (Char -> Char -> Char) -> Char -> Vector Char -> Vector Char
forall a b. (a -> b -> b) -> b -> Vector a -> Vector b
Vector.scanr
   scanr1 :: (Char -> Char -> Char) -> Vector Char -> Vector Char
scanr1 Char -> Char -> Char
f Vector Char
v | Vector Char -> Bool
forall a. Vector a -> Bool
Vector.null Vector Char
v = Vector Char
forall a. Vector a
Vector.empty
              | Bool
otherwise = (Char -> Char -> Char) -> Vector Char -> Vector Char
forall a. (a -> a -> a) -> Vector a -> Vector a
Vector.scanr1 Char -> Char -> Char
f Vector Char
v
   mapAccumL :: (a -> Char -> (a, Char)) -> a -> Vector Char -> (a, Vector Char)
mapAccumL a -> Char -> (a, Char)
f a
a0 Vector Char
t = (a
a', Vector Char -> Vector Char
forall a. Vector a -> Vector a
Vector.reverse (Vector Char -> Vector Char) -> Vector Char -> Vector Char
forall a b. (a -> b) -> a -> b
$ String -> Vector Char
forall a. [a] -> Vector a
Vector.fromList String
l')
      where (a
a', String
l') = ((a, String) -> Char -> (a, String))
-> (a, String) -> Vector Char -> (a, String)
forall a b. (a -> b -> a) -> a -> Vector b -> a
Vector.foldl (a, String) -> Char -> (a, String)
fc (a
a0, []) Vector Char
t
            fc :: (a, String) -> Char -> (a, String)
fc (a
a, String
l) Char
c = (Char -> String -> String
forall a. a -> [a] -> [a]
:String
l) (Char -> String) -> (a, Char) -> (a, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> Char -> (a, Char)
f a
a Char
c
   mapAccumR :: (a -> Char -> (a, Char)) -> a -> Vector Char -> (a, Vector Char)
mapAccumR a -> Char -> (a, Char)
f a
a0 Vector Char
t = (a
a', String -> Vector Char
forall a. [a] -> Vector a
Vector.fromList String
l')
      where (a
a', String
l') = (Char -> (a, String) -> (a, String))
-> (a, String) -> Vector Char -> (a, String)
forall a b. (a -> b -> b) -> b -> Vector a -> b
Vector.foldr Char -> (a, String) -> (a, String)
fc (a
a0, []) Vector Char
t
            fc :: Char -> (a, String) -> (a, String)
fc Char
c (a
a, String
l) = (Char -> String -> String
forall a. a -> [a] -> [a]
:String
l) (Char -> String) -> (a, Char) -> (a, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> Char -> (a, Char)
f a
a Char
c

   takeWhile :: (Vector Char -> Bool)
-> (Char -> Bool) -> Vector Char -> Vector Char
takeWhile Vector Char -> Bool
_ = (Char -> Bool) -> Vector Char -> Vector Char
forall a. (a -> Bool) -> Vector a -> Vector a
Vector.takeWhile
   dropWhile :: (Vector Char -> Bool)
-> (Char -> Bool) -> Vector Char -> Vector Char
dropWhile Vector Char -> Bool
_ = (Char -> Bool) -> Vector Char -> Vector Char
forall a. (a -> Bool) -> Vector a -> Vector a
Vector.dropWhile
   break :: (Vector Char -> Bool)
-> (Char -> Bool) -> Vector Char -> (Vector Char, Vector Char)
break Vector Char -> Bool
_ = (Char -> Bool) -> Vector Char -> (Vector Char, Vector Char)
forall a. (a -> Bool) -> Vector a -> (Vector a, Vector a)
Vector.break
   span :: (Vector Char -> Bool)
-> (Char -> Bool) -> Vector Char -> (Vector Char, Vector Char)
span Vector Char -> Bool
_ = (Char -> Bool) -> Vector Char -> (Vector Char, Vector Char)
forall a. (a -> Bool) -> Vector a -> (Vector a, Vector a)
Vector.span
   spanMaybe :: s
-> (s -> Vector Char -> Maybe s)
-> (s -> Char -> Maybe s)
-> Vector Char
-> (Vector Char, Vector Char, s)
spanMaybe s
s0 s -> Vector Char -> Maybe s
_ft s -> Char -> Maybe s
fc Vector Char
v = case (Int -> Char -> (s -> Either s (Int, s)) -> s -> Either s (Int, s))
-> (s -> Either s (Int, s))
-> Vector Char
-> s
-> Either s (Int, s)
forall a b. (Int -> a -> b -> b) -> b -> Vector a -> b
Vector.ifoldr Int -> Char -> (s -> Either s (Int, s)) -> s -> Either s (Int, s)
forall a a.
a -> Char -> (s -> Either a (a, s)) -> s -> Either a (a, s)
g s -> Either s (Int, s)
forall a b. a -> Either a b
Left Vector Char
v s
s0
                           of Left s
s' -> (Vector Char
v, Vector Char
forall a. Vector a
Vector.empty, s
s')
                              Right (Int
i, s
s') | (Vector Char
prefix, Vector Char
suffix) <- Int -> Vector Char -> (Vector Char, Vector Char)
forall a. Int -> Vector a -> (Vector a, Vector a)
Vector.splitAt Int
i Vector Char
v -> (Vector Char
prefix, Vector Char
suffix, s
s')
      where g :: a -> Char -> (s -> Either a (a, s)) -> s -> Either a (a, s)
g a
i Char
c s -> Either a (a, s)
cont s
s | Just s
s' <- s -> Char -> Maybe s
fc s
s Char
c = s -> Either a (a, s)
cont s
s'
                         | Bool
otherwise = (a, s) -> Either a (a, s)
forall a b. b -> Either a b
Right (a
i, s
s)
   spanMaybe' :: s
-> (s -> Vector Char -> Maybe s)
-> (s -> Char -> Maybe s)
-> Vector Char
-> (Vector Char, Vector Char, s)
spanMaybe' s
s0 s -> Vector Char -> Maybe s
_ft s -> Char -> Maybe s
fc Vector Char
v = case (Int -> Char -> (s -> Either s (Int, s)) -> s -> Either s (Int, s))
-> (s -> Either s (Int, s))
-> Vector Char
-> s
-> Either s (Int, s)
forall a b. (Int -> a -> b -> b) -> b -> Vector a -> b
Vector.ifoldr' Int -> Char -> (s -> Either s (Int, s)) -> s -> Either s (Int, s)
forall a a.
a -> Char -> (s -> Either a (a, s)) -> s -> Either a (a, s)
g s -> Either s (Int, s)
forall a b. a -> Either a b
Left Vector Char
v s
s0
                            of Left s
s' -> (Vector Char
v, Vector Char
forall a. Vector a
Vector.empty, s
s')
                               Right (Int
i, s
s') | (Vector Char
prefix, Vector Char
suffix) <- Int -> Vector Char -> (Vector Char, Vector Char)
forall a. Int -> Vector a -> (Vector a, Vector a)
Vector.splitAt Int
i Vector Char
v -> (Vector Char
prefix, Vector Char
suffix, s
s')
      where g :: a -> Char -> (s -> Either a (a, s)) -> s -> Either a (a, s)
g a
i Char
c s -> Either a (a, s)
cont s
s | Just s
s' <- s -> Char -> Maybe s
fc s
s Char
c = s -> Either a (a, s) -> Either a (a, s)
seq s
s' (s -> Either a (a, s)
cont s
s')
                         | Bool
otherwise = (a, s) -> Either a (a, s)
forall a b. b -> Either a b
Right (a
i, s
s)
   find :: (Char -> Bool) -> Vector Char -> Maybe Char
find = (Char -> Bool) -> Vector Char -> Maybe Char
forall a. (a -> Bool) -> Vector a -> Maybe a
Vector.find
   elem :: Char -> Vector Char -> Bool
elem = Char -> Vector Char -> Bool
forall a. Eq a => a -> Vector a -> Bool
Vector.elem

   {-# INLINE all #-}
   {-# INLINE any #-}
   {-# INLINE break #-}
   {-# INLINE characterPrefix #-}
   {-# INLINE concatMap #-}
   {-# INLINE dropWhile #-}
   {-# INLINE elem #-}
   {-# INLINE find #-}
   {-# INLINE foldl   #-}
   {-# INLINE foldl'  #-}
   {-# INLINE foldr   #-}
   {-# INLINE map #-}
   {-# INLINE mapAccumL #-}
   {-# INLINE mapAccumR #-}
   {-# INLINE scanl #-}
   {-# INLINE scanl1 #-}
   {-# INLINE scanr #-}
   {-# INLINE scanr1 #-}
   {-# INLINE singleton #-}
   {-# INLINE span #-}
   {-# INLINE spanMaybe #-}
   {-# INLINE spanMaybe' #-}
   {-# INLINE splitCharacterPrefix #-}
   {-# INLINE takeWhile #-}