A Rope
is similar to a list, but has fast (constant time) concatenation at both ends, and fast concatenation of two Rope
s.
It's slightly slower (O(n + operations) instead of O(n)) to iterate through, so you should convert it to a List
if you plan to use it repeatedly.
Internally the Rope
is a tree of lists.
empty : Rope a
An empty rope.
singleton : a -> Rope a
Create a rope with only one element:
singleton 1234 |> toList
--> [ 1234 ]
singleton "hi" |> toList
--> [ "hi" ]
append : a -> Rope a -> Rope a
Add an element to the end of a list.
append 1 (fromList [2,3]) |> toList
--> [2,3,1]
append 1 empty |> toList
--> [1]
Complexity: O(1)
prepend : a -> Rope a -> Rope a
Add an element to the front of a list.
prepend 1 (fromList [2,3]) |> toList
--> [1,2,3]
prepend 1 empty |> toList
--> [1]
Complexity: O(1)
fromList : List a -> Rope a
Build a rope from a list.
Complexity: O(1)
map : (a -> b) -> Rope a -> Rope b
Apply a function to every element of a rope.
map sqrt (fromList [1,4,9]) |> toList
--> [1,2,3]
map not (fromList [True,False,True]) |> toList
--> [False,True,False]
So map func (fromList [ a, b, c ])
is the same as fromList [ func a, func b, func c ]
Complexity: O(n)
indexedMap : (Basics.Int -> a -> b) -> Rope a -> Rope b
Same as map
but the function is also applied to the index of each
element (starting at zero).
indexedMap Tuple.pair (fromList [ "Tom", "Sue", "Bob" ]) |> toList
--> [ ( 0, "Tom" ), ( 1, "Sue" ), ( 2, "Bob" ) ]
Complexity: O(n)
foldl : (a -> b -> b) -> b -> Rope a -> b
Reduce a rope from the left.
foldl (+) 0 (fromList [ 1, 2, 3 ])
--> 6
foldl (::) [] (fromList [ 1, 2, 3 ])
--> [ 3, 2, 1 ]
So foldl step state [1,2,3]
is like saying:
state
|> step 1
|> step 2
|> step 3
Complexity: O(n)
foldr : (a -> b -> b) -> b -> Rope a -> b
Reduce a rope from the right.
foldr (+) 0 (fromList [ 1, 2, 3 ])
--> 6
foldr (::) [] (fromList [ 1, 2, 3 ])
--> [ 1, 2, 3 ]
So foldr step state [1,2,3]
is like saying:
state
|> step 3
|> step 2
|> step 1
filter : (a -> Basics.Bool) -> Rope a -> Rope a
Keep elements that satisfy the test.
filter (\n -> modBy 2 n == 0) (fromList [1,2,3,4,5,6]) |> toList
--> [2,4,6]
filterMap : (a -> Maybe b) -> Rope a -> Rope b
Filter out certain values. For example, maybe you have a bunch of strings from an untrusted source and you want to turn them into numbers:
numbers : List Int
numbers =
filterMap String.toInt [ "3", "hi", "12", "4th", "May" ]
-- numbers == [3, 12]
toList : Rope a -> List a
Convert a rope into the equivalent list.
Complexity: O(n)
length : Rope a -> Basics.Int
Determine the length of a rope.
length (fromList [1,2,3])
--> 3
reverse : Rope a -> Rope a
Reverse a rope.
reverse [ 1, 2, 3, 4 ] == [ 4, 3, 2, 1 ]
member : a -> Rope a -> Basics.Bool
Figure out whether a rope contains a value.
member 9 (fromList [1,2,3,4])
--> False
member 4 (fromList [1,2,3,4])
--> True
all : (a -> Basics.Bool) -> Rope a -> Basics.Bool
Determine if all elements satisfy some test.
all (\n -> modBy 2 n == 0) (fromList [2,4])
--> True
all (\n -> modBy 2 n == 0) (fromList [2,3])
--> False
all (\n -> modBy 2 n == 0) (fromList [])
--> True
any : (a -> Basics.Bool) -> Rope a -> Basics.Bool
Determine if any elements satisfy some test.
any (\n -> modBy 2 n == 0) (fromList [ 2, 3 ])
--> True
any (\n -> modBy 2 n == 0) (fromList [ 1, 3 ])
--> False
any (\n -> modBy 2 n == 0) (fromList [])
--> False
maximum : Rope comparable -> Maybe comparable
Find the maximum element in a non-empty rope.
maximum (fromList [ 1, 4, 2 ])
--> Just 4
maximum (fromList [])
--> Nothing
minimum : Rope comparable -> Maybe comparable
Find the minimum element in a non-empty rope.
minimum (fromList [ 3, 2, 1 ])
--> Just 1
minimum (fromList [])
--> Nothing
sum : Rope number -> number
Get the sum of the rope elements.
sum (fromList [ 1, 2, 3 ])
--> 6
sum (fromList [ 1, 1, 1 ])
--> 3
sum (fromList [])
--> 0
product : Rope number -> number
Get the product of the rope elements.
product (fromList [ 2, 2, 2 ])
--> 8
product (fromList [ 3, 3, 3 ])
--> 27
product (fromList [])
--> 1
appendTo : Rope a -> Rope a -> Rope a
Put two ropes together, the second after the first.
appendTo (fromList [ 1, 1, 2 ]) (fromList [ 3, 5, 8 ]) |> toList
--> [ 1, 1, 2, 3, 5, 8 ]
appendTo (fromList [ 'a', 'b' ]) (fromList [ 'c' ]) |> toList
--> [ 'a', 'b', 'c' ]
Complexity: O(1)
prependTo : Rope a -> Rope a -> Rope a
Put two ropes together, the first after the second.
prependTo (fromList [ 1, 1, 2 ]) (fromList [ 3, 5, 8 ]) |> toList
--> [ 3, 5, 8, 1, 1, 2 ]
prependTo (fromList [ 'a', 'b' ]) (fromList [ 'c' ]) |> toList
--> [ 'c', 'a', 'b' ]
Complexity: O(1)
concat : Rope (Rope a) -> Rope a
Concatenate a bunch of ropes into a single rope:
concat (fromList [ fromList [ 1, 2 ], fromList [ 3 ], fromList [ 4, 5 ] ]) |> toList
--> [ 1, 2, 3, 4, 5 ]
Complexity: O(n), in practice it can be O(1) if the top level is the result of fromList
concatMap : (a -> Rope b) -> Rope a -> Rope b
Map a given function onto a list and flatten the resulting lists.
concatMap f xs == concat (map f xs)
isEmpty : Rope a -> Basics.Bool
Determine if a rope is empty.
isEmpty (fromList [])
--> True