module Foundation.Collection.Sequential
( Sequential(..)
) where
import Foundation.Internal.Base
import Foundation.Collection.Element
import Foundation.Collection.Collection
import qualified Foundation.Collection.List as ListExtra
import qualified Data.List
import qualified Foundation.Array.Unboxed as UV
import qualified Foundation.Array.Boxed as BA
import qualified Foundation.String.UTF8 as S
class (IsList c, Item c ~ Element c, Monoid c, Collection c) => Sequential c where
take :: Int -> c -> c
take n = fst . splitAt n
revTake :: Int -> c -> c
revTake n = fst . revSplitAt n
drop :: Int -> c -> c
drop n = snd . splitAt n
revDrop :: Int -> c -> c
revDrop n = snd . revSplitAt n
splitAt :: Int -> c -> (c,c)
splitAt n c = (take n c, drop n c)
revSplitAt :: Int -> c -> (c,c)
revSplitAt n c = (revTake n c, revDrop n c)
splitOn :: (Element c -> Bool) -> c -> [c]
break :: (Element c -> Bool) -> c -> (c,c)
break predicate = span (not . predicate)
breakElem :: Eq (Element c) => Element c -> c -> (c,c)
breakElem c = break (== c)
intersperse :: Element c -> c -> c
intercalate :: Monoid (Item c) => Element c -> c -> Element c
intercalate xs xss = mconcatCollection (intersperse xs xss)
span :: (Element c -> Bool) -> c -> (c,c)
span predicate = break (not . predicate)
filter :: (Element c -> Bool) -> c -> c
partition :: (Element c -> Bool) -> c -> (c,c)
partition predicate c = (filter predicate c, filter (not . predicate) c)
reverse :: c -> c
uncons :: c -> Maybe (Element c, c)
unsnoc :: c -> Maybe (c, Element c)
snoc :: c -> Element c -> c
cons :: Element c -> c -> c
find :: (Element c -> Bool) -> c -> Maybe (Element c)
sortBy :: (Element c -> Element c -> Ordering) -> c -> c
singleton :: Element c -> c
head :: NonEmpty c -> Element c
head nel = maybe (error "head") fst $ uncons (getNonEmpty nel)
last :: NonEmpty c -> Element c
last nel = maybe (error "last") snd $ unsnoc (getNonEmpty nel)
tail :: NonEmpty c -> c
tail nel = maybe (error "tail") snd $ uncons (getNonEmpty nel)
init :: NonEmpty c -> c
init nel = maybe (error "init") fst $ unsnoc (getNonEmpty nel)
isPrefixOf :: Eq (Element c) => c -> c -> Bool
default isPrefixOf :: Eq c => c -> c -> Bool
isPrefixOf c1 c2
| len1 > len2 = False
| len1 == len2 = c1 == c2
| otherwise = c1 == take len1 c2
where
len1 = length c1
len2 = length c2
isSuffixOf :: Eq (Element c) => c -> c -> Bool
default isSuffixOf :: Eq c => c -> c -> Bool
isSuffixOf c1 c2
| len1 > len2 = False
| len1 == len2 = c1 == c2
| otherwise = c1 == revTake len1 c2
where
len1 = length c1
len2 = length c2
mconcatCollection :: (Monoid (Item c), Sequential c) => c -> Element c
mconcatCollection c = mconcat (toList c)
instance Sequential [a] where
take = Data.List.take
drop = Data.List.drop
revTake = ListExtra.revTake
revDrop = ListExtra.revDrop
splitAt = Data.List.splitAt
revSplitAt = ListExtra.revSplitAt
splitOn = ListExtra.wordsWhen
break = Data.List.break
intersperse = Data.List.intersperse
span = Data.List.span
filter = Data.List.filter
partition = Data.List.partition
reverse = Data.List.reverse
uncons = ListExtra.uncons
unsnoc = ListExtra.unsnoc
snoc c e = c `mappend` [e]
cons e c = e : c
find = Data.List.find
sortBy = Data.List.sortBy
singleton = (:[])
isPrefixOf = Data.List.isPrefixOf
isSuffixOf = Data.List.isSuffixOf
instance UV.PrimType ty => Sequential (UV.UArray ty) where
take = UV.take
revTake = UV.revTake
drop = UV.drop
revDrop = UV.revDrop
splitAt = UV.splitAt
revSplitAt = UV.revSplitAt
splitOn = UV.splitOn
break = UV.break
breakElem = UV.breakElem
intersperse = UV.intersperse
span = UV.span
filter = UV.filter
reverse = UV.reverse
uncons = UV.uncons
unsnoc = UV.unsnoc
snoc = UV.snoc
cons = UV.cons
find = UV.find
sortBy = UV.sortBy
singleton = fromList . (:[])
instance Sequential (BA.Array ty) where
take = BA.take
drop = BA.drop
splitAt = BA.splitAt
revTake = BA.revTake
revDrop = BA.revDrop
revSplitAt = BA.revSplitAt
splitOn = BA.splitOn
break = BA.break
intersperse = BA.intersperse
span = BA.span
reverse = BA.reverse
filter = BA.filter
unsnoc = BA.unsnoc
uncons = BA.uncons
snoc = BA.snoc
cons = BA.cons
find = BA.find
sortBy = BA.sortBy
singleton = fromList . (:[])
instance Sequential S.String where
take = S.take
drop = S.drop
splitAt = S.splitAt
revTake = S.revTake
revDrop = S.revDrop
revSplitAt = S.revSplitAt
splitOn = S.splitOn
break = S.break
breakElem = S.breakElem
intersperse = S.intersperse
span = S.span
filter = S.filter
reverse = S.reverse
unsnoc = S.unsnoc
uncons = S.uncons
snoc = S.snoc
cons = S.cons
find = S.find
sortBy = S.sortBy
singleton = S.singleton