Changes

Jump to navigation Jump to search
336 bytes removed ,  18:39, 1 December 2023
m
Text replacement - "syntaxhighlight" to "pre"
The most general function type is <code>function(*)</code>. It's the type of all function items. The following query for example goes through a list of XQuery items and, if it is a function item, prints its arity:
<syntaxhighlight pre lang="'xquery"'>
for $item in (1, 'foo', fn:concat#3, function($a) { 42 * $a })
where $item instance of function(*)
The notation for specifying argument and return types is quite intuitive, as it closely resembles the function declaration. The XQuery function
<syntaxhighlight pre lang="'xquery"'>
declare function local:char-at(
$str as xs:string,
Function types can also be nested. As an example we take <code>local:on-sequences</code>, which takes a function defined on single items and makes it work on sequences as well:
<syntaxhighlight pre lang="'xquery"'>
declare function local:on-sequences(
$fun as function(item()) as item()*
|
<ul><li>Square all numbers from 1 to 10:
<syntaxhighlight pre lang="'xquery"'>
fn:for-each(1 to 10, math:pow(?, 2))
</pre>
</li>
<li>Apply a list of functions to a string:
<syntaxhighlight pre lang="'xquery"'>
let $fs := (
fn:upper-case#1,
</li>
<li>Process each item of a sequence with the arrow operator:
<syntaxhighlight pre lang="'xquery"'>
("one", "two", "three") => fn:for-each(fn:upper-case(?))
</pre>
| '''XQuery 1.0'''
|At the core, for-each is nothing else than a simple FLWOR expression:
<syntaxhighlight pre lang="'xquery"'>
declare function local:for-each(
$seq as item()*,
| '''Examples'''
|<ul><li>All even integers until 10:
<syntaxhighlight pre lang="'xquery"'>
fn:filter(1 to 10, function($x) { $x mod 2 eq 0 })
</pre>
</li>
<li>Strings that start with an upper-case letter:
<syntaxhighlight pre lang="'xquery"'>
let $first-upper := function($str) {
let $first := fn:substring($str, 1, 1)
</li>
<li>Inefficient prime number generator:
<syntaxhighlight pre lang="'xquery"'>
let $is-prime := function($x) {
$x gt 1 and (every $y in 2 to ($x - 1) satisfies $x mod $y ne 0)
| '''Note'''
|<code>fn:filter</code> can be easily implemented with <code>fn:for-each</code>:
<syntaxhighlight pre lang="'xquery"'>
declare function local:filter($seq, $pred) {
for-each(
| '''XQuery 1.0'''
|At the core, for-each is nothing else than a filter expression:
<syntaxhighlight pre lang="'xquery"'>
declare function local:filter(
$seq as item()*,
| '''Examples'''
|<ul><li>Adding one to the numbers at odd positions:
<syntaxhighlight pre lang="'xquery"'>
fn:for-each-pair(
fn:for-each(1 to 10, function($x) { $x mod 2 }),
</li>
<li>Line numbering:
<syntaxhighlight pre lang="'xquery"'>
let $number-words := function($str) {
fn:string-join(
</pre>
''Result:''
<syntaxhighlight pre lang="'xquery"'>
1: how
2: are
</li>
<li>Checking if a sequence is sorted:
<syntaxhighlight pre lang="'xquery"'>
let $is-sorted := function($seq) {
every $b in
|- valign="top"
| '''XQuery 1.0'''
|<syntaxhighlight pre lang="'xquery"'>
declare function local:for-each-pair(
$seq1 as item()*,
Calculating the ''product'' of a sequence of integers for example is easy in <code>Java</code>:
<syntaxhighlight pre lang="java">
public int product(int[] seq) {
int result = 1;
|The ''left fold'' traverses the {{Code|$input}} from the left.
The query <code>fn:fold-left(1 to 5, 0, $f)</code>, for example, would be evaluated as:
<syntaxhighlight pre lang="'xquery"'>
$f($f($f($f($f(0, 1), 2), 3), 4), 5)
</pre>
| '''Examples'''
|<ul><li>Product of a sequence of integers:
<syntaxhighlight pre lang="'xquery"'>
fn:fold-left(1 to 5, 1,
function($result, $curr) { $result * $curr }
</li>
<li>Illustrating the evaluation order:
<syntaxhighlight pre lang="'xquery"'>
fn:fold-left(1 to 5, '$seed',
concat('$f(', ?, ', ', ?, ')')
</li>
<li>Building a decimal number from digits:
<syntaxhighlight pre lang="'xquery"'>
let $from-digits := fold-left(?, 0,
function($n, $d) { 10 * $n + $d }
| '''XQuery 1.0'''
|As folds are more general than ''FLWOR'' expressions, the implementation isn't as concise as the former ones:
<syntaxhighlight pre lang="'xquery"'>
declare function local:fold-left(
$input as item()*,
|The ''right fold'' traverses the {{Code|$input}} from the right.
The query <code>fn:fold-right(1 to 5, 0, $f)</code>, for example, would be evaluated as:
<syntaxhighlight pre lang="'xquery"'>
$f(1, $f(2, $f(3, $f(4, $f(5, 0)))))
</pre>
| '''Examples'''
|<ul><li>Product of a sequence of integers:
<syntaxhighlight pre lang="'xquery"'>
fn:fold-right(1 to 5, 1,
function($curr, $result) { $result * $curr }
</li>
<li>Illustrating the evaluation order:
<syntaxhighlight pre lang="'xquery"'>
fn:fold-right(1 to 5, '$seed',
concat('$f(', ?, ', ', ?, ')')
</li>
<li>Reversing a sequence of items:
<syntaxhighlight pre lang="'xquery"'>
let $reverse := fn:fold-right(?, (),
function($item, $rev) {
|- valign="top"
| '''XQuery 1.0'''
|<syntaxhighlight pre lang="'xquery"'>
declare function local:fold-right(
$input as item()*,
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu