Queue FIFO (first-in first-out) data structure.
It has the same API as List
and it takes constant time O(1)
for enqueue
, head
and length
operations.
It takes constant time in average case for dequeue
θ(1)
.
A queue of values. You can think about a Queue representation like about List, where left side is the input and right is output:
fromList [ 2, 4, 6, 8 ]
-- indx -> [ 3, 2, 1, 0 ] ->
empty : Queue a
Create an empty queue:
empty == fromList []
singleton : a -> Queue a
Create a queue with only one element:
singleton 1234 == fromList [ 1234 ]
singleton "hi" == fromList [ "hi" ]
fromList : List a -> Queue a
Create a queue from List
.
It take time proportional to O(N)
.
repeat : Basics.Int -> a -> Queue a
Create a queue with n copies of a value:
repeat 3 "hi"
== fromList [ "hi", "hi", "hi" ]
range : Basics.Int -> Basics.Int -> Queue Basics.Int
Create a queue of numbers, every element increasing one. You give the lowest and the highest number that should be in the queue.
range 3 6 == fromList [ 6, 5, 4, 3 ]
range 3 3 == fromList [ 3 ]
range 6 3 == fromList []
head (range 3 6) == Just 3
head : Queue a -> Maybe a
Extract the next element of a queue:
head empty == Nothing
head (singleton 0) == Just 0
head (fromList [ 1, 2, 3 ]) == Just 3
It takes constant time O(1)
.
tail : Queue a -> Maybe (Queue a)
Extract the rest of the list:
tail (fromList [ 1, 2, 3 ]) == Just [ 1, 2 ]
tail empty == Nothing
It takes constant time in average case θ(1)
(Ω(1)
and O(N)
).
take : Basics.Int -> Queue a -> Queue a
Take the first n
members of a queue:
take 2 (fromList [ 1, 2, 3 ]) == formList [ 2, 3 ]
It takes constant time in case when n <= 0 || n >= N
.
drop : Basics.Int -> Queue a -> Queue a
Drop the first n
members of a queue:
drop 2 (fromList [ 1, 2, 3 ]) == formList [ 1 ]
It takes constant time in case when n <= 0 || n >= N
.
partition : (a -> Basics.Bool) -> Queue a -> ( Queue a, Queue a )
Partition a queue based on some test. The first queue contains all values that satisfy the test, and the second queue contains all the value that do not.
[ 0, 1, 2, 3, 4, 5 ]
|> fromList
|> partition (\x -> x < 3)
== ( fromList [ 0, 1, 2 ], fromList [ 3, 4, 5 ] )
[ 0, 1, 2, 3, 4, 5 ]
|> fromList
|> partition isEven
== ( fromList [ 0, 2, 4 ], fromList [ 1, 3, 5 ] )
unzip : Queue ( a, b ) -> ( Queue a, Queue b )
Decompose a queue of tuples into a tuple of queues.
[ ( 0, True )
, ( 17, False )
, ( 1337, True )
]
|> fromList
|> unzip
== ( fromList [ 0, 17, 1337 ]
, fromList [ True, False, True ]
)
toList : Queue a -> List a
Convert a queue (FIFO) to list (LIFO):
toList (fromList [ 1, 2, 3 ]) == [ 1, 2, 3 ]
empty
|> enqueue 3
|> enqueue 2
|> enqueue 1
|> toList
== [ 1, 2, 3 ]
It takes time proportional to O(N)
.
enqueue : a -> Queue a -> Queue a
Add an element to the queue.
enqueue 1 empty == fromList [ 1 ]
enqueue 1 (fromList [ 2, 3, 4 ])
== fromList [ 1, 2, 3, 4 ]
empty
|> enqueue 1
|> enqueue 2
|> enqueue 3
== fromList [ 3, 2, 1 ]
It takes constant time O(1)
.
dequeue : Queue a -> Maybe ( a, Queue a )
Extract and remove the first element from the queue:
dequeue empty == Nothing
dequeue (singleton 1) == Just ( 1, empty )
dequeue (fromList [ 1, 2, 3 ])
== Just ( 3, fromList [ 1, 2 ] )
It takes constant time in average case θ(1)
(Ω(1)
and O(N)
).
length : Queue a -> Basics.Int
Determine the length of a queue:
length empty == 0
length (fromList [ 3, 2, 1 ]) == 3
It takes constant time O(1)
.
isEmpty : Queue a -> Basics.Bool
Determine if a queue is empty.
isEmpty (fromList []) == True
isEmpty (fromList [ 1, 2, 3 ]) == False
isEqual : Queue a -> Queue a -> Basics.Bool
Determine if two queues are equal.
It takes constant time O(1)
when lengths are different.
any : (a -> Basics.Bool) -> Queue a -> Basics.Bool
Determine if any elements satisfy some test:
any isEven (fromList [ 2, 3 ]) == True
any isEven (fromList [ 1, 3 ]) == False
any isEven (fromList []) == False
all : (a -> Basics.Bool) -> Queue a -> Basics.Bool
Determine if all elements satisfy some test.
all isEven (fromList [ 2, 4 ]) == True
all isEven (fromList [ 2, 3 ]) == False
all isEven (fromList []) == True
member : a -> Queue a -> Basics.Bool
Figure out whether a queue contains a value.
member 9 (fromList []) == False
member 9 (fromList [ 1, 2, 3, 4 ]) == False
member 4 (fromList [ 1, 2, 3, 4 ]) == True
maximum : Queue comparable -> Maybe comparable
Find the maximum element in a non-empty queue:
maximum (fromList [ 1, 4, 2 ]) == Just 4
maximum (fromList []) == Nothing
minimum : Queue comparable -> Maybe comparable
Find the minimum element in a non-empty queue:
minimum (fromList [ 3, 2, 1 ]) == Just 1
minimum (fromList []) == Nothing
sum : Queue number -> number
Get the sum of the queue elements:
sum (fromList [ 1, 2, 3 ]) == 6
sum (fromList [ 1, 1, 1 ]) == 3
sum (fromList []) == 0
product : Queue number -> number
Get the product of the queue elements:
product (from List [ 2, 2, 2 ]) == 8
product (from List [ 3, 3, 3 ]) == 27
product (from List []) == 1
map : (a -> b) -> Queue a -> Queue b
Apply a function to every element of a queue:
map sqrt (fromList [ 1, 4, 9 ])
== fromList [ 1, 2, 3 ]
indexedMap : (Basics.Int -> a -> b) -> Queue a -> Queue b
Same as map but the function is also applied to the index of each element (starting at zero):
indexedMap Tuple.pair (fromList [ "A", "B", "C" ])
== fromList [ ( 2, "A" ), ( 1, "B" ), ( 0, "C" ) ]
foldr : (a -> b -> b) -> b -> Queue a -> b
Reduce queue from left to right (or from the oldest to newest):
empty
|> enqueue 3
|> enqueue 2
|> enqueue 1
|> foldr (+) 0
=== 6
empty
|> enqueue 3
|> enqueue 2
|> enqueue 1
|> foldr (::) []
== [ 1, 2, 3 ]
So foldr step state (fromList [ 1, 2, 3 ])
is like saying:
state
|> step 3
|> step 2
|> step 1
foldl : (a -> b -> b) -> b -> Queue a -> b
Reduce queue from right to left (or from the newest to oldest):
empty
|> enqueue 3
|> enqueue 2
|> enqueue 1
|> foldl (+) 0
=== 6
empty
|> enqueue 3
|> enqueue 2
|> enqueue 1
|> foldl (::) []
== [ 3, 2, 1 ]
So foldl step state (fromList [ 1, 2, 3 ])
is like saying:
state
|> step 1
|> step 2
|> step 3
filter : (a -> Basics.Bool) -> Queue a -> Queue a
Keep elements that satisfy the test:
filter isEven (fromList [ 1, 2, 3, 4, 5, 6 ])
== fromList [ 2, 4, 6 ]
filterMap : (a -> Maybe b) -> Queue a -> Queue 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:
[ "3", "hi", "12", "4th", "May" ]
|> fromList
|> filterMap String.toInt
== fromList [ 3, 12 ]
reverse : Queue a -> Queue a
Reverse the queue:
reverse (fromList [ 1, 2, 3, 4 ])
== fromList [ 4, 3, 2, 1 ]
append : Queue a -> Queue a -> Queue a
Put two queues together:
append (fromList [ 1, 1, 2 ]) (fromList [ 3, 5, 8 ])
== fromList [ 1, 1, 2, 3, 5, 8 ]
append (fromList [ 'a', 'b' ]) (fromList [ 'c' ])
== fromList [ 'a', 'b', 'c' ]
concat : Queue (Queue a) -> Queue a
Concatenate a bunch of queues into a single queue:
[ fromList [ 1, 2 ]
, fromList [ 3 ]
, fromList [ 4, 5 ]
]
|> fromList
|> concat
== fromList [ 1, 2, 3, 4, 5 ]
concatMap : (a -> Queue b) -> Queue a -> Queue b
Map a given function onto a queue and flatten the resulting queues:
concatMap f xs == concat (map f xs)
intersperse : a -> Queue a -> Queue a
Places the given value between all members of the given queue.
intersperse ">" (fromList [ "third", "second", "first" ])
== fromList [ "third", ">", "second", ">", "first" ]
map2 : (a -> b -> result) -> Queue a -> Queue b -> Queue result
Combine two queues, combining them with the given function. If one queue is longer, the extra elements are dropped.
map2 (+)
(fromList [ 1, 2, 3 ])
(fromList [ 4, 5, 6 ])
== fromList [ 5, 7, 9 ]
map2 Tuple.pair
(fromList [ "alice", "bob", "chuck" ])
(fromList [ 2, 5, 7, 8 ])
== fromList
[ ( "alice", 5 )
, ( "bob", 7 )
, ( "chuck", 8 )
]
map3 : (a -> b -> c -> result) -> Queue a -> Queue b -> Queue c -> Queue result
map4 : (a -> b -> c -> d -> result) -> Queue a -> Queue b -> Queue c -> Queue d -> Queue result
map5 : (a -> b -> c -> d -> e -> result) -> Queue a -> Queue b -> Queue c -> Queue d -> Queue e -> Queue result
sort : Queue comparable -> Queue comparable
Sort values from lowest to highest:
sort (fromList [ 3, 1, 5 ]) == fromList [ 5, 3, 1 ]
sortBy : (a -> comparable) -> Queue a -> Queue a
Sort values by a derived property:
alice =
{ name = "Alice", height = 1.62 }
bob =
{ name = "Bob", height = 1.85 }
chuck =
{ name = "Chuck", height = 1.76 }
[ chuck, alice, bob ]
|> fromList
|> sortBy .name
== fromList [ chuck, bob, alice ]
[ chuck, alice, bob ]
|> fromList
|> sortBy .height
== fromList [ bob, chuck, alice ]
[ "cat", "mouse" ]
|> fromList
|> sortBy String.length
== fromList [ "mouse", "cat" ]
sortWith : (a -> a -> Basics.Order) -> Queue a -> Queue a
Sort values with a custom comparison function:
flippedComparison a b =
case compare a b of
LT -> GT
EQ -> EQ
GT -> LT
[ 5, 4, 3, 2, 1 ]
|> fromList
|> sortWith flippedComparison
== fromList [ 1, 2, 3, 4, 5 ]