Skip to content

Commit

Permalink
Add stripSuffix and stripPrefix
Browse files Browse the repository at this point in the history
These are definable for any ListLike and potentially useful
(Data.List exposes stripPrefix). On the other hand, Text has
special implementations of both of them that we'd like to
take advantage of, so it belongs in the typeclass itself.
  • Loading branch information
jhance committed Jul 23, 2016
1 parent 42e70e9 commit 53aa6aa
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Data/ListLike.hs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ module Data.ListLike
group, inits, tails,
-- ** Predicates
isPrefixOf, isSuffixOf, isInfixOf,
-- ** Modify based on predicate
stripPrefix, stripSuffix,
-- * Searching lists
-- ** Searching by equality
elem, notElem,
Expand Down
14 changes: 14 additions & 0 deletions src/Data/ListLike/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,19 @@ class (FoldableLL full item, Monoid full) =>
any (isPrefixOf needle) thetails
where thetails = asTypeOf (tails haystack) [haystack]

------------------------------ Conditionally modify based on predicates
{- | Remove a prefix from a listlike if possible -}
stripPrefix :: Eq item => full -> full -> Maybe full
stripPrefix xs ys = if xs `isPrefixOf` ys
then Just $ drop (length xs) ys
else Nothing

{- | Remove a suffix from a listlike if possible -}
stripSuffix :: Eq item => full -> full -> Maybe full
stripSuffix xs ys = if xs `isSuffixOf` ys
then Just $ take (length ys - length xs) ys
else Nothing

------------------------------ Searching
{- | True if the item occurs in the list -}
elem :: Eq item => item -> full -> Bool
Expand Down Expand Up @@ -607,6 +620,7 @@ instance ListLike [a] a where
isPrefixOf = L.isPrefixOf
isSuffixOf = L.isSuffixOf
isInfixOf = L.isInfixOf
stripPrefix = L.stripPrefix
elem = L.elem
notElem = L.notElem
find = L.find
Expand Down
2 changes: 2 additions & 0 deletions src/Data/ListLike/Text/Text.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ instance ListLike T.Text Char where
tails = fromList . T.tails
isPrefixOf = T.isPrefixOf
isSuffixOf = T.isSuffixOf
stripPrefix = T.stripPrefix
stripSuffix = T.stripSuffix
elem = T.isInfixOf . T.singleton
find = T.find
filter = T.filter
Expand Down
2 changes: 2 additions & 0 deletions src/Data/ListLike/Text/TextLazy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ instance ListLike T.Text Char where
tails = fromList . T.tails
isPrefixOf = T.isPrefixOf
isSuffixOf = T.isSuffixOf
stripPrefix = T.stripPrefix
stripSuffix = T.stripSuffix
elem = T.isInfixOf . T.singleton
find = T.find
filter = T.filter
Expand Down
9 changes: 9 additions & 0 deletions testsrc/runtests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ For license and copyright information, see the file COPYRIGHT
-}
module Main where

import Control.Applicative
import Test.QuickCheck
import qualified Data.ListLike as LL
import qualified Data.Foldable as F
Expand Down Expand Up @@ -110,6 +111,11 @@ prop_isSuffixOf f1 f2 = LL.isSuffixOf f1 f2 ==
(isSuffixOf (LL.toList f1) (LL.toList f2))
prop_isInfixOf f1 f2 = LL.isInfixOf f1 f2 ==
(isInfixOf (LL.toList f1) (LL.toList f2))
prop_stripPrefix f1 f2 = (LL.toList <$> LL.stripPrefix f1 f2) ==
(stripPrefix (LL.toList f1) (LL.toList f2))
prop_stripPrefix2 f1 f2 = (LL.toList <$> LL.stripPrefix f1 (f1 <> f2)) ==
(stripPrefix (LL.toList f1) (LL.toList $ f1 <> f2))
prop_stripSuffix f1 f2 = LL.stripSuffix f1 (f2 <> f1) == Just f2
prop_elem f i = LL.elem i f == elem i (LL.toList f)
prop_notElem f i = LL.notElem i f == notElem i (LL.toList f)
prop_find f func = LL.find func f == find func (LL.toList f)
Expand Down Expand Up @@ -269,6 +275,9 @@ allt = [apf "empty" (t prop_empty),
apf "isPrefixOf" (t prop_isPrefixOf),
apf "isSuffixOf" (t prop_isSuffixOf),
apf "isInfixOf" (t prop_isInfixOf),
apf "stripPrefix" (t prop_stripPrefix),
apf "stripPrefix2" (t prop_stripPrefix2),
apf "stripSuffix" (t prop_stripSuffix),
apf "elem" (t prop_elem),
apf "notElem" (t prop_notElem),
apf "find" (t prop_find),
Expand Down

0 comments on commit 53aa6aa

Please sign in to comment.