Skip to content

Commit 79d4cc8

Browse files
safarelipaf31
authored andcommitted
add stripPrefix and Pattern for Data.List (#120)
* add stripPrefix and Pattern for Data.List * define Newtype for Pattern a * fix redundant parens
1 parent 6d1c863 commit 79d4cc8

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"test": "pulp test"
77
},
88
"devDependencies": {
9-
"pulp": "^10.0.4",
10-
"purescript-psa": "^0.5.0-rc.1",
9+
"pulp": "^11.0.0",
10+
"purescript-psa": "^0.5.1",
1111
"rimraf": "^2.6.1"
1212
}
1313
}

src/Data/List.purs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ module Data.List
5656
, sort
5757
, sortBy
5858

59+
, Pattern(..)
60+
, stripPrefix
5961
, slice
6062
, take
6163
, takeWhile
@@ -94,13 +96,14 @@ import Prelude
9496
import Control.Alt ((<|>))
9597
import Control.Alternative (class Alternative)
9698
import Control.Lazy (class Lazy, defer)
97-
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM)
99+
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM, tailRecM2)
98100

99101
import Data.Bifunctor (bimap)
100102
import Data.Foldable (class Foldable, foldr, any, foldl)
101103
import Data.List.Types (List(..), (:))
102104
import Data.List.Types (NonEmptyList(..)) as NEL
103105
import Data.Maybe (Maybe(..))
106+
import Data.Newtype (class Newtype)
104107
import Data.NonEmpty ((:|))
105108
import Data.Traversable (sequence)
106109
import Data.Tuple (Tuple(..))
@@ -476,6 +479,32 @@ sortBy cmp = mergeAll <<< sequences
476479
-- Sublists --------------------------------------------------------------------
477480
--------------------------------------------------------------------------------
478481

482+
-- | A newtype used in cases where there is a list to be matched.
483+
newtype Pattern a = Pattern (List a)
484+
485+
derive instance eqPattern :: Eq a => Eq (Pattern a)
486+
derive instance ordPattern :: Ord a => Ord (Pattern a)
487+
derive instance newtypePattern :: Newtype (Pattern a) _
488+
489+
instance showPattern :: Show a => Show (Pattern a) where
490+
show (Pattern s) = "(Pattern " <> show s <> ")"
491+
492+
493+
-- | If the list starts with the given prefix, return the portion of the
494+
-- | list left after removing it, as a Just value. Otherwise, return Nothing.
495+
-- | * `stripPrefix (Pattern (1:Nil)) (1:2:Nil) == Just (2:Nil)`
496+
-- | * `stripPrefix (Pattern Nil) (1:Nil) == Just (1:Nil)`
497+
-- | * `stripPrefix (Pattern (2:Nil)) (1:Nil) == Nothing`
498+
-- |
499+
-- | Running time: `O(n)` where `n` is the number of elements to strip.
500+
stripPrefix :: forall a. Eq a => Pattern a -> List a -> Maybe (List a)
501+
stripPrefix (Pattern p') s = tailRecM2 go p' s
502+
where
503+
go prefix input = case prefix, input of
504+
Cons p ps, Cons i is | p == i -> Just $ Loop { a: ps, b: is }
505+
Nil, is -> Just $ Done is
506+
_, _ -> Nothing
507+
479508
-- | Extract a sublist by a start and end index.
480509
slice :: Int -> Int -> List ~> List
481510
slice start end xs = take (end - start) (drop start xs)

test/Test/Data/List.purs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Data.List.NonEmpty as NEL
55
import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, log)
77
import Data.Foldable (foldMap, foldl)
8-
import Data.List (List(..), (..), length, range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, partition, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, unsnoc, init, tail, last, head, insertBy, insert, snoc, null, singleton, fromFoldable, transpose, mapWithIndex, (:))
8+
import Data.List (List(..), (..), stripPrefix, Pattern(..), length, range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, partition, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, unsnoc, init, tail, last, head, insertBy, insert, snoc, null, singleton, fromFoldable, transpose, mapWithIndex, (:))
99
import Data.Maybe (Maybe(..), isNothing, fromJust)
1010
import Data.Monoid.Additive (Additive(..))
1111
import Data.NonEmpty ((:|))
@@ -19,6 +19,11 @@ testList :: forall eff. Eff (assert :: ASSERT, console :: CONSOLE | eff) Unit
1919
testList = do
2020
let l = fromFoldable
2121

22+
log "strip prefix"
23+
assert $ stripPrefix (Pattern (1:Nil)) (1:2:Nil) == Just (2:Nil)
24+
assert $ stripPrefix (Pattern Nil) (1:Nil) == Just (1:Nil)
25+
assert $ stripPrefix (Pattern (2:Nil)) (1:Nil) == Nothing
26+
2227
log "singleton should construct an list with a single value"
2328
assert $ singleton 1 == l [1]
2429
assert $ singleton "foo" == l ["foo"]

0 commit comments

Comments
 (0)