Difference between revisions of "Higher-Order Functions Module"
Jump to navigation
Jump to search
| Line 8: | Line 8: | ||
==hof:id== | ==hof:id== | ||
| + | |||
{| width='100%' | {| width='100%' | ||
|- | |- | ||
| Line 38: | Line 39: | ||
==hof:const== | ==hof:const== | ||
| + | |||
{| width='100%' | {| width='100%' | ||
|- | |- | ||
| Line 96: | Line 98: | ||
==hof:until== | ==hof:until== | ||
| + | |||
{| width='100%' | {| width='100%' | ||
|- | |- | ||
| Line 119: | Line 122: | ||
</pre> | </pre> | ||
returns {{Code|5.000000000053722}}. | returns {{Code|5.000000000053722}}. | ||
| + | |} | ||
| + | |||
| + | ==hof:scan-left== | ||
| + | |||
| + | {{Mark|Introduced with Version 8.1}}: | ||
| + | |||
| + | {| width='100%' | ||
| + | |- | ||
| + | | width='120' | '''Signatures''' | ||
| + | |{{Func|hof:scan-left|$seq as item()*, $start as item()*, $f as function(item()*, item()) as item()*|item()*}} | ||
| + | |- | ||
| + | | '''Summary''' | ||
| + | |This function is similar to [[Higher-Order Functions#fn:fold-left|fn:fold-left]], but it returns a list of successive reduced values from the left. It is equivalent to: | ||
| + | <pre class="brush:xquery"> | ||
| + | declare function hof:scan-left($seq, $acc, $f) { | ||
| + | if(empty($seq)) then $acc else ( | ||
| + | $acc, | ||
| + | hof:scan-left(tail($seq), $f($acc, head($seq)), $f) | ||
| + | ) | ||
| + | }; | ||
| + | </pre> | ||
| + | |- | ||
| + | | '''Examples''' | ||
| + | | | ||
| + | * Returns triangular numbers: | ||
| + | <pre class="brush:xquery"> | ||
| + | hof:scan-left(1 to 10, 0, function($a, $b) { $a + $b }) | ||
| + | </pre> | ||
| + | |} | ||
| + | |||
| + | ==hof:take-while== | ||
| + | |||
| + | {{Mark|Introduced with Version 8.1}}: | ||
| + | |||
| + | {| width='100%' | ||
| + | |- | ||
| + | | width='120' | '''Signatures''' | ||
| + | |{{Func|hof:take-while|$seq as item()*, $pred as function(item()) as xs:boolean|item()*}} | ||
| + | |- | ||
| + | | '''Summary''' | ||
| + | |The function returns items of <code>$seq</code> as long as the predicate <code>$pred</code> is satisfied. It is equivalent to: | ||
| + | <pre class="brush:xquery"> | ||
| + | declare function hof:take-while($seq, $pred) { | ||
| + | if(empty($seq) or not($pred(head($seq)))) then () else ( | ||
| + | head($seq), | ||
| + | hof:take-while(tail($seq), $pred) | ||
| + | ) | ||
| + | }; | ||
| + | </pre> | ||
| + | |- | ||
| + | | '''Examples''' | ||
| + | | | ||
| + | * Computes at most 100 random integers, but stops if an integer is smaller than 10: | ||
| + | <pre class="brush:xquery"> | ||
| + | hof:take-while( | ||
| + | for $i in 1 to 100 | ||
| + | return random:integer(50), | ||
| + | function($x) { $x >= 10 } | ||
| + | ) | ||
| + | </pre> | ||
|} | |} | ||
| Line 161: | Line 224: | ||
=Changelog= | =Changelog= | ||
| + | |||
| + | ;Version 8.1 | ||
| + | |||
| + | * Added: [[#hof:scan-left|hof:scan-left]], [[#hof:take-while|hof:take-while]] | ||
;Version 7.2 | ;Version 7.2 | ||
Revision as of 11:56, 6 March 2015
This XQuery Module adds some useful higher-order functions, additional to the Higher-Order Functions provided by the official specification.
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.
Functions
hof:id
| Signatures | hof:id($expr as item()*) as item()*
|
| Summary | Returns its argument unchanged. This function isn't useful on its own, but can be used as argument to other higher-order functions. |
| Examples |
let $sort-by := function($f, $seq) {
for $x in $seq
order by $f($x)
return $x
}
let $sort := $sort-by(hof:id#1, ?),
$reverse-sort := $sort-by(function($x) { -$x }, ?)
return (
$sort((1, 5, 3, 2, 4)),
'|',
$reverse-sort((1, 5, 3, 2, 4))
)
returns: |
hof:const
| Signatures | hof:const($expr as item()*, $ignored 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 |
let $zip-sum := function($f, $seq1, $seq2) {
sum(map-pairs($f, $seq1, $seq2))
}
let $sum-all := $zip-sum(function($a, $b) { $a + $b }, ?, ?),
$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)
)
let $insert-with := function($f, $map, $k, $v) {
let $old := $map($k),
$new := if($old) then $f($v, $old) else $v
return map:new(($map, map { $k: $new }))
}
let $map := map { 'foo': 1 }
let $add := $insert-with(function($a, $b) {$a + $b}, ?, ?, ?),
$insert := $insert-with(hof:const#2, ?, ?, ?)
return (
$add($map, 'foo', 2)('foo'),
$insert($map, 'foo', 42)('foo')
)
returns |
hof:fold-left1
| Signatures | hof:fold-left1($seq as item()+, $f as function(item()*, item()) as item()*) as item()*
|
| Summary | Works the same as fn:fold-left, but doesn't need a seed, because the sequence must be non-empty. |
| Examples |
|
hof:until
| Signatures | hof:until($pred as function(item()*) as xs:boolean, $f as function(item()*) as item()*, $start as item()*) as item()*
|
| Summary | Applies the function $f to the initial value $start until the predicate $pred applied to the result returns true().
|
| Examples |
let $sqrt := function($x as xs:double) as xs:double {
hof:until(
function($res) { abs($res * $res - $x) < 0.00001 },
function($guess) { ($guess + $x div $guess) div 2 },
$x
)
}
return $sqrt(25)
returns |
hof:scan-left
| Signatures | hof:scan-left($seq as item()*, $start as item()*, $f 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:
declare function hof:scan-left($seq, $acc, $f) {
if(empty($seq)) then $acc else (
$acc,
hof:scan-left(tail($seq), $f($acc, head($seq)), $f)
)
};
|
| Examples |
hof:scan-left(1 to 10, 0, function($a, $b) { $a + $b })
|
hof:take-while
| Signatures | hof:take-while($seq as item()*, $pred as function(item()) as xs:boolean) as item()*
|
| Summary | The function returns items of $seq as long as the predicate $pred is satisfied. It is equivalent to:
declare function hof:take-while($seq, $pred) {
if(empty($seq) or not($pred(head($seq)))) then () else (
head($seq),
hof:take-while(tail($seq), $pred)
)
};
|
| Examples |
hof:take-while(
for $i in 1 to 100
return random:integer(50),
function($x) { $x >= 10 }
)
|
hof:top-k-by
| Signatures | hof:top-k-by($seq as item()*, $sort-key as function(item()) as item(), $k as xs:integer) as item()*
|
| Summary | Returns the $k items in $seq that are greatest when sorted by the result of $f applied to the item. The function is a much more efficient implementation of the following scheme:
(for $x in $seq order by $sort-key($x) descending return $x )[position() <= $k] |
| Examples |
|
hof:top-k-with
| Signatures | hof:top-k-with($seq as item()*, $lt as function(item(), item()) as xs:boolean, $k as xs:integer) as item()*
|
| Summary | Returns the $k items in $seq that are greatest when sorted in the order of the less-than predicate $lt. The function is a general version of hof:top-k-by($seq, $sort-key, $k).
|
| Examples |
|
Changelog
- 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