-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathqueue.xqm
115 lines (107 loc) · 2.62 KB
/
queue.xqm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
xquery version "3.0";
(:~
: A simple queue implementation.
:
: @author Leo Woerteler <[email protected]>
: @version 0.1
: @license BSD 2-Clause License
:)
module namespace queue = 'http://www.woerteler.de/xquery/modules/queue';
import module namespace pair = 'http://www.woerteler.de/xquery/modules/pair'
at 'pair.xqm';
import module namespace list = 'http://www.woerteler.de/xquery/modules/list'
at 'list.xqm';
(:~
: The empty queue.
: @return the empty queue
:)
declare %public function queue:empty() {
pair:new(list:nil(), list:nil())
};
(:~
: Enqueues the given value into the given queue.
:
: @param $x the value to enqueue
: @param $queue the queue
: @return the queue with <code>$x</code> added at the back
:)
declare %public function queue:enqueue(
$x as item()*,
$queue
) as function(*) {
pair:deconstruct(
$queue,
function($hd, $tl) {
list:match(
$hd,
function() { pair:new(list:cons($x, list:nil()), list:nil()) },
function($_, $__) {
pair:new($hd, list:cons($x, $tl))
}
)
}
)
};
(:~
: Matches the given queue and calls the corresponding callback for the empty
: or non-empty queue.
: @param $queue queue to match on
: @param $empty no-argument callback for the empty queue
: @param $non-empty callback for the non-empty queue that takes the first element
and the tai of the queue
:)
declare %public function queue:match(
$queue as function(*),
$empty as function() as item()*,
$non-empty as function(item()*, function(*)) as item()*
) as item()* {
pair:deconstruct(
$queue,
function($xs, $ys) {
list:match(
$xs,
$empty,
function($x, $xss) {
$non-empty(
$x,
list:match(
$xss,
function() { pair:new(list:reverse($ys), list:nil()) },
function($_, $__) { pair:new($xss, $ys) }
)
)
}
)
}
)
};
(:~
: Returns the tail of the queue.
:
: @return tail of the queue
: @error queue:EMPTYQUE when the queue is empty
:)
declare %public function queue:tail(
$queue as function(*)
) as function(*) {
queue:match(
$queue,
function() { error(xs:QName('queue:EMPTYQUE'), 'empty queue') },
function($_, $tail) { $tail }
)
};
(:~
: Returns the head of the queue.
:
: @return value at the head of the queue
: @error queue:EMPTYQUE when the queue is empty
:)
declare %public function queue:peek(
$queue as function(*)
) as item()* {
queue:match(
$queue,
function() { error(xs:QName('queue:EMPTYQUE'), 'empty queue') },
function($x, $_) { $x }
)
};