Difference between revisions of "Higher-Order Functions Module"
m (Text replacement - "</syntaxhighlight>" to "</pre>") |
|||
Line 66: | Line 66: | ||
) | ) | ||
}; | }; | ||
− | </ | + | </pre> |
|- valign="top" | |- valign="top" | ||
| '''Examples''' | | '''Examples''' | ||
Line 73: | Line 73: | ||
<syntaxhighlight lang="xquery"> | <syntaxhighlight lang="xquery"> | ||
hof:scan-left(1 to 10, 0, function($a, $b) { $a + $b }) | hof:scan-left(1 to 10, 0, function($a, $b) { $a + $b }) | ||
− | </ | + | </pre> |
|} | |} | ||
Line 96: | Line 96: | ||
return $item | return $item | ||
)[position() <= $k] | )[position() <= $k] | ||
− | </ | + | </pre> |
|- valign="top" | |- valign="top" | ||
| '''Examples''' | | '''Examples''' | ||
Line 154: | Line 154: | ||
$sum-left((1, 1, 1, 1, 1), 1 to 5) | $sum-left((1, 1, 1, 1, 1), 1 to 5) | ||
) | ) | ||
− | </ | + | </pre> |
* Another use-case: When inserting a key into a map, {{Code|$f}} decides how to combine the new value with a possibly existing old one. {{Code|hof:const}} here means ignoring the old value, so that's normal insertion. | * Another use-case: When inserting a key into a map, {{Code|$f}} decides how to combine the new value with a possibly existing old one. {{Code|hof:const}} here means ignoring the old value, so that's normal insertion. | ||
<syntaxhighlight lang="xquery"> | <syntaxhighlight lang="xquery"> | ||
Line 169: | Line 169: | ||
$ins($map, 'foo', 42)('foo') | $ins($map, 'foo', 42)('foo') | ||
) | ) | ||
− | </ | + | </pre> |
returns {{Code|3 42}} | returns {{Code|3 42}} | ||
|} | |} |
Revision as of 18:31, 1 December 2023
This XQuery Module adds some useful higher-order functions, additional to the Higher-Order Functions provided by the official specification.
With Version 11, many functions have been removed in favor of new features of XQuery 4:
BaseX 10 | XQuery 4 |
hof:drop-while
|
fn:items-starting-where
|
hof:id
|
fn:identity
|
hof:until
|
fn:iterate-while
|
hof:take-while
|
fn:items-before
|
Contents
Conventions
All functions in this module are assigned to the http://basex.org/modules/hof
namespace, which is statically bound to the hof
prefix.
Loops
hof:fold-left1
Signature | hof:fold-left1( $input as item()+, $action as function(item()*, item()) as item()* ) as item()* |
Summary | Works the same as fn:fold-left, but does not need a seed, because the sequence must be non-empty. |
Examples |
|
hof:scan-left
Signature | hof:scan-left( $input as item()*, $zero as item()*, $action as function(item()*, item()) as item()* ) as item()* |
Summary | This function is similar to fn:fold-left, but it returns a list of successive reduced values from the left. It is equivalent to:
<syntaxhighlight lang="xquery"> declare function hof:scan-left($input, $acc, $action) { if(empty($input)) then $acc else ( $acc, hof:scan-left(tail($input), $action($acc, head($input)), $action) ) }; |
Examples |
<syntaxhighlight lang="xquery"> hof:scan-left(1 to 10, 0, function($a, $b) { $a + $b }) |
Sorting
hof:top-k-by
Signature | hof:top-k-by( $input as item()*, $key as function(item()) as item(), $k as xs:integer ) as item()* |
Summary | Returns the $k items in $input that are greatest when sorted by the result of $key applied to the item. The function is a much more efficient implementation of the following scheme:
<syntaxhighlight lang="xquery"> (for $item in $input order by $key($item) descending return $item )[position() <= $k] |
Examples |
|
hof:top-k-with
Signature | hof:top-k-with( $input as item()*, $comparator as function(item(), item()) as xs:boolean, $k as xs:integer ) as item()* |
Summary | Returns the $k items in $input that are greatest when sorted in the order of the less-than predicate $comparator . The function is a general version of hof:top-k-by .
|
Examples |
|
Identity
hof:const
Signature | hof:const( $input as item()*, $ignore as item()* ) as item()* |
Summary | Returns its first argument unchanged and ignores the second. This function isn’t useful on its own, but can be used as argument to other higher-order functions, e.g., when a function combining two values is expected and one only wants to retain the left one. |
Examples |
<syntaxhighlight lang="xquery"> let $zip-sum := function($f, $seq1, $seq2) { sum(for-each-pair($seq1, $seq2, $f)) } let $sum-all := $zip-sum(function($a, $b) { $a + $b }, ?, ?) let $sum-left := $zip-sum(hof:const#2, ?, ?) return ( $sum-all((1, 1, 1, 1, 1), 1 to 5), $sum-left((1, 1, 1, 1, 1), 1 to 5) )
<syntaxhighlight lang="xquery"> let $insert-with := function($f, $map, $k, $v) { let $old := $map($k) let $new := if($old) then $f($v, $old) else $v return map:merge(($map, map:entry($k, $new))) } let $map := map { 'foo': 1 } let $add := $insert-with(function($a, $b) { $a + $b }, ?, ?, ?) let $ins := $insert-with(hof:const#2, ?, ?, ?) return ( $add($map, 'foo', 2)('foo'), $ins($map, 'foo', 42)('foo') ) returns |
Changelog
- Version 11.0
- Removed:
hof:until
(replaced withfn:iterate-while
,hof:if
(replaced withfn:identity
,hof:drop-while
(replaced withfn:items-starting-where
),hof:take-while
(replaced withfn:items-before
)
- Version 9.5
- Added:
hof:drop-while
- Version 8.1
- Added:
hof:scan-left
,hof:take-while
- Version 7.2
- Added:
hof:top-k-by
,hof:top-k-with
- Removed: hof:iterate
- Version 7.0
- module added