Skip to content

Commit 1613071

Browse files
committed
Add index based OMap operations
1 parent 24ed930 commit 1613071

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

src/Data/Map/Ordered/OMap.purs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ module Data.Map.Ordered.OMap
55
, fromFoldable
66
, fromFoldableWithIndex
77
, insert
8+
, insertAt
89
, isEmpty
910
, keys
11+
, keyIndex
1012
, lookup
13+
, moveLeft
14+
, moveRight
15+
, moveTo
1116
, singleton
1217
, toUnfoldable
1318
, unionWith
@@ -137,6 +142,15 @@ insert k v (OMap m) =
137142
unit
138143
) -- Anonymous function wrapper added to delay computation of the default case
139144

145+
keyIndex :: forall k v. Eq k => k -> OMap k v -> Maybe Int
146+
keyIndex k (OMap m) = Array.findIndex (eq k <<< fst) m
147+
148+
insertAt :: forall k v. Ord k => Int -> k -> v -> OMap k v -> Maybe (OMap k v)
149+
insertAt i k v m = do
150+
let
151+
OMap m' = delete k m
152+
OMap <$> Array.insertAt i (k /\ v) m'
153+
140154
delete :: forall k v. Ord k => k -> OMap k v -> OMap k v
141155
delete k om = filterKeys ((/=) k) om
142156

@@ -152,3 +166,16 @@ alter f k om = case mOldValue, mNewValue of
152166
mOldValue = lookup k om
153167

154168
mNewValue = f mOldValue
169+
170+
moveTo :: forall k v. Ord k => Int -> k -> OMap k v -> Maybe (OMap k v)
171+
moveTo i k m = do
172+
v <- lookup k m
173+
let
174+
m' = delete k m
175+
insertAt i k v m'
176+
177+
moveLeft :: forall k v. Ord k => k -> OMap k v -> Maybe (OMap k v)
178+
moveLeft k m = keyIndex k m >>= \i -> moveTo (i - 1) k m
179+
180+
moveRight :: forall k v. Ord k => k -> OMap k v -> Maybe (OMap k v)
181+
moveRight k m = keyIndex k m >>= \i -> moveTo (i + 1) k m

test/Data/Map/Ordered.purs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module Data.Map.Ordered.Spec
2+
( orderedMapSpec
3+
) where
4+
5+
import Prelude
6+
7+
import Data.Map.Ordered.OMap (fromFoldable, moveLeft, moveRight)
8+
import Data.Maybe (Maybe(..))
9+
import Data.Tuple.Nested ((/\))
10+
import Test.Spec (Spec, describe, it)
11+
import Test.Spec.Assertions (shouldEqual)
12+
13+
orderedMapSpec :: Spec Unit
14+
orderedMapSpec = do
15+
describe "moveLeft" do
16+
it "fails on the first element" do
17+
let
18+
m = fromFoldable [ "foo" /\ 1, "bar" /\ 2, "baz" /\ 3 ]
19+
moveLeft "foo" m `shouldEqual` Nothing
20+
it "moves the second element" do
21+
let
22+
m = fromFoldable [ "foo" /\ 1, "bar" /\ 2, "baz" /\ 3 ]
23+
moveLeft "bar" m `shouldEqual`
24+
(Just $ fromFoldable [ "bar" /\ 2, "foo" /\ 1, "baz" /\ 3 ])
25+
describe "moveRight" do
26+
it "fails on the last element" do
27+
let
28+
m = fromFoldable [ "foo" /\ 1, "bar" /\ 2, "baz" /\ 3 ]
29+
moveRight "baz" m `shouldEqual` Nothing
30+
it "moves the second element" do
31+
let
32+
m = fromFoldable [ "foo" /\ 1, "bar" /\ 2, "baz" /\ 3 ]
33+
moveRight "bar" m `shouldEqual`
34+
(Just $ fromFoldable [ "foo" /\ 1, "baz" /\ 3, "bar" /\ 2 ])

test/Main.purs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Data.Array.Extra.Spec (arrayExtraSpec)
66
import Data.BigInt.Argonaut.Spec (bigIntSpec)
77
import Data.Cursor.Spec (cursorSpec)
88
import Data.Foldable.Extra.Spec (foldableExtraSpec)
9+
import Data.Map.Ordered.Spec (orderedMapSpec)
910
import Data.String.Extra.Spec (stringExtraSpec)
1011
import Effect (Effect)
1112
import Effect.Aff (launchAff_)
@@ -23,3 +24,4 @@ main =
2324
stringExtraSpec
2425
assocMapSpec
2526
bigIntSpec
27+
orderedMapSpec

0 commit comments

Comments
 (0)