Changes

Jump to navigation Jump to search
no edit summary
All functions in this module are assigned to the <code><nowiki>http://basex.org/modules/hof</nowiki></code> namespace, which is statically bound to the {{Code|hof}} prefix.<br/>
=FunctionsLoops==hof:id== {| width='100%'|-| width='120' | '''Signatures'''|{{Func|hof:id|$expr as item()*|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'''|* {{Code|hof:id(1 to 5)}} returns {{Code|1 2 3 4 5}}* With higher-order functions:<pre class="brush:xquery">let $sort := sort(?, hof:id#1)let $reverse-sort := sort(?, function($x) { -$x })return ( $sort((1, 5, 3, 2, 4)), '|', $reverse-sort((1, 5, 3, 2, 4)))</pre>returns: <code>1 2 3 4 5 | 5 4 3 2 1</code>|} ==hof:const== {| width='100%'|-| width='120' | '''Signatures'''|{{Func|hof:const|$expr as item()*, $ignored as item()*|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'''|* {{Code|hof:const(42, 1337)}} returns {{Code|42}}.* With higher-order functions:<pre class="brush: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))</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.<pre class="brush: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'))</pre>returns {{Code|3 42}}|}
==hof:fold-left1==
|-
| '''Summary'''
|Works the same as [[Higher-Order Functions#fn:fold-left|fn:fold-left]], but doesn't does not need a seed, because the sequence must be non-empty.
|-
| '''Examples'''
|-
| '''Summary'''
|Applies the predicate function {{Code|$fpred}} to the initial value {{Code|$start}} until . If the predicate result is {{Code|false}}, {{Code|$predf}} applied to is invoked with the start value – or, subsequently, with the result of this function – until the predicate function returns {{Code|true()}}.
|-
| '''Examples'''
|
* {{Code|Doubles a numeric value until a maximum is reached:<syntaxhighlight lang="xquery">hof:until( function($xoutput) { $x output ge 1000 }, function($yinput ) { 2 * $y input }, 1)}} returns {{Code|1024}}.</syntaxhighlight>* Calculating Calculates the square-root of a number by iteratively improving an initial guess:<pre classsyntaxhighlight lang="brush:xquery">let $sqrt := function($x input as xs:double) as xs:double {
hof:until(
function($resresult) { abs($res result * $res result - $xinput) < 0.00001 }, function($guess) { ($guess + $x input div $guess) div 2 }, $xinput
)
}
return $sqrt(25)
</presyntaxhighlight>returns * Returns {{Code|5.000000000053722OK}}., as the predicate is evaluated first:<syntaxhighlight lang="xquery">hof:until( function($_) { true() }, function($_) { error() }, 'OK')</syntaxhighlight>
|}
| '''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 classsyntaxhighlight lang="brush:xquery">
declare function hof:scan-left($seq, $acc, $f) {
if(empty($seq)) then $acc else (
)
};
</presyntaxhighlight>
|-
| '''Examples'''
|
* Returns triangular numbers:
<pre classsyntaxhighlight lang="brush:xquery">
hof:scan-left(1 to 10, 0, function($a, $b) { $a + $b })
</presyntaxhighlight>
|}
| '''Summary'''
|The function returns items of <code>$seq</code> as long as the predicate <code>$pred</code> is satisfied. It is equivalent to:
<pre classsyntaxhighlight lang="brush:xquery">
declare function hof:take-while($seq, $pred) {
if(empty($seq) or not($pred(head($seq)))) then () else (
)
};
</presyntaxhighlight>
|-
| '''Examples'''
|
* Computes at most 100 random integers, but stops if an integer is smaller than 10:
<pre classsyntaxhighlight lang="brush:xquery">
hof:take-while(
(1 to 100) ! random:integer(50),
function($x) { $x >= 10 }
)
</presyntaxhighlight>
|}
 
=Sorting=
==hof:top-k-by==
| '''Summary'''
|Returns the {{Code|$k}} items in {{Code|$seq}} that are greatest when sorted by the result of {{Code|$f}} applied to the item. The function is a much more efficient implementation of the following scheme:
<pre classsyntaxhighlight lang="brush:xquery">
(for $x in $seq
order by $sort-key($x) descending
return $x
)[position() <= $k]
</presyntaxhighlight>
|-
| '''Examples'''
* {{Code|hof:top-k-with(1 to 1000, function($a, $b) { $a lt $b }, 5)}} returns {{Code|1000 999 998 997 996}}
* {{Code|hof:top-k-with(-5 to 5, function($a, $b) { abs($a) gt abs($b) }, 5)}} returns {{Code|0 1 -1 2 -2}}
|}
 
=IDs=
 
==hof:id==
 
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|hof:id|$expr as item()*|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'''
|
* {{Code|hof:id(1 to 5)}} returns {{Code|1 2 3 4 5}}
* With higher-order functions:
<syntaxhighlight lang="xquery">
let $sort := sort(?, (), hof:id#1)
let $reverse-sort := sort(?, (), function($x) { -$x })
return (
$sort((1, 5, 3, 2, 4)),
'|',
$reverse-sort((1, 5, 3, 2, 4))
)
</syntaxhighlight>
returns: <code>1 2 3 4 5 | 5 4 3 2 1</code>
|}
 
==hof:const==
 
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|hof:const|$expr as item()*, $ignored as item()*|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'''
|
* {{Code|hof:const(42, 1337)}} returns {{Code|42}}.
* With higher-order functions:
<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>
* 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">
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')
)
</syntaxhighlight>
returns {{Code|3 42}}
|}
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu