Skip to content

Instantly share code, notes, and snippets.

@CliffordAnderson
Last active January 3, 2024 15:40
Show Gist options
  • Save CliffordAnderson/0c45f973ef45228ab685 to your computer and use it in GitHub Desktop.
Save CliffordAnderson/0c45f973ef45228ab685 to your computer and use it in GitHub Desktop.
Simple examples of higher-order functions and partial function application in XQuery

##Examples of Higher-Order Functions in XQuery

Here are a few examples of higher-order functions in XQuery. For more examples, see the very nice discussion of higher-order functions in XQuery 3.0 at the BaseX website.

N.B. In some implementations, these functions may not be implemented or may have different names/function signatures. The first four functions have been tested using Saxon PE and the second four using Zorba.

xquery version "3.0";
declare namespace math = "http://www.w3.org/2005/xpath-functions/math";
(: a higher-order function that returns a function as its value :)
declare function local:pow($i as xs:integer) as function(*)
{
function($a as xs:integer) {math:pow($a, $i)}
};
let $pow2 := local:pow(2)
return $pow2(2)
xquery version "3.0";
declare namespace math = "http://www.w3.org/2005/xpath-functions/math";
(: assigns a built-in math function to a variable (see http://docs.basex.org/wiki/XQuery_3.0); :)
(: the number after the pound symbol indicates its arity (i.e., the number of arguments it accepts :)
let $pow := math:pow#2
(: partial function application; returns a function as its value :)
let $pow2 := $pow(?, 2)
return $pow2(2)
xquery version "3.0";
(: a higher-order function; accepts a function as an argument :)
let $fun := function($oper, $a, $b) {$oper(($a, $b))}
(: lambda expression or anonymous function declaration :)
let $add := function($a) {$a[1] + $a[2]}
let $sub := function($a) {$a[1] - $a[2]}
(: partial functional application; returns a function as its value :)
let $fun-add := $fun($add, ?, ?)
let $fun-sub := $fun($sub, ?, ?)
return ($fun-add(1,1), $fun-sub(1,1))
xquery version "3.0";
(: a higher-order function; accepts a function as an argument :)
let $fun := function($oper as function(xs:decimal*) as xs:decimal, $a as xs:decimal, $b as xs:decimal) as xs:decimal {$oper(($a, $b))}
(: lambda expression or anonymous function declaration :)
let $add := function($a as xs:decimal*) as xs:decimal {$a[1] + $a[2]}
let $sub := function($a as xs:decimal*) as xs:decimal {$a[1] - $a[2]}
(: partial functional application; returns a function as its value :)
let $fun-add := $fun($add, ?, ?)
let $fun-sub := $fun($sub, ?, ?)
return ($fun-add(1,5), $fun-sub(1,5))
xquery version "3.0";
(: takes a list of names and returns the total of all their lengths :)
let $seq := ("James", "John", "Mary", "Martha")
let $fun := function($accumulator as xs:integer, $name as xs:string) as xs:integer {fn:string-length($name) + $accumulator}
return fold-left($seq, 0, $fun)
xquery version "3.0";
(: takes a list of integers and returns the sum using fold-right :)
let $seq := (1,2,3,4)
let $fun := function($x as xs:integer, $accumulator as xs:integer) as xs:integer {($x * $x) + $accumulator}
return fold-right($seq, 0, $fun)
xquery version "3.0";
(: applies a function to the each item in the sequence :)
(: akin to the simple map operator :)
let $seq := ("James", "John", "Mary", "Martha")
return for-each($seq, fn:upper-case#1)
xquery version "3.0";
(: applies a function to pairs of items in sequences :)
let $seq1 := ("James", "John", "Mary", "Martha")
let $seq2 := ("tall", "short", "tall", "short")
let $fun := function($a as xs:string, $b as xs:string) {fn:concat($a, " is ", $b)}
return for-each-pair($seq1, $seq2, $fun)
xquery version "3.0";
let $seq := 1 to 10
let $fun := function($a as xs:integer) as xs:boolean {$a gt 4}
return filter($seq, $fun)
@CliffordAnderson
Copy link
Author

I'd be very glad to know whether there's a better way of creating addition and subtraction functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment