`f:arity' now considers partial applications

master
Mike Gerwitz 2014-11-29 01:16:59 -05:00
parent f62e6a8e33
commit c64cefe931
3 changed files with 55 additions and 32 deletions

View File

@ -28,21 +28,28 @@
<!--
Attempt to retrieve arity of dynamic function
Attempt to retrieve arity of dynamic function @var{fnref}
The input must be a function reference. Partially applied function
references will have an arity equivalent to the remaining parameters
in the original function.
If the arity cannot be determined, -1 is returned.
@var{fnref} must be a dynamic function reference satisfying
@code{f:is-ref}. Partially applied function references will have an
arity equivalent to the free parameters in the target function.
-->
<function name="f:arity" as="xs:decimal">
<param name="fnref" as="element(f:ref)" />
<function name="f:arity" as="xs:integer">
<param name="fnref" as="item()+" />
<sequence select="if ( $fnref/@arity ) then
$fnref/@arity
<variable name="ref" as="element( f:ref )"
select="$fnref[ 1 ]" />
<variable name="arity" as="xs:integer"
select="$ref/@arity" />
<variable name="partial" as="xs:integer"
select="if ( $ref/@partial ) then
$ref/@partial
else
-1" />
0" />
<sequence select="$arity - $partial" />
</function>
</stylesheet>

View File

@ -71,12 +71,15 @@
<sequence select="$args" />
</variable>
<variable name="argn" as="xs:decimal"
select="count( $argout )" />
<variable name="arity" as="xs:decimal"
<!-- note that, if FNREF is partially applied, then this arity
represents the arity of the partially applied function, _not_
the target function -->
<variable name="arity" as="xs:integer"
select="f:arity( $ref )" />
<variable name="argn" as="xs:integer"
select="count( $args )" />
<choose>
<when test="$argn eq $arity">
<sequence select="_f:apply-partial( $ref, $argout )" />
@ -87,7 +90,7 @@
select="$ref">
<with-param name="args" select="$argout" />
<with-param name="arity" select="$arity" />
<with-param name="argn" select="$argn" />
<with-param name="argn" select="count( $argout )" />
</apply-templates>
</when>
@ -96,7 +99,7 @@
<sequence select="$ref/@*" />
<attribute name="partial"
select="count( $args )" />
select="count( $argout )" />
<sequence select="$ref/*" />
</f:ref>

View File

@ -31,6 +31,13 @@
select="namespace-uri-for-prefix(
'foo', root(.)/element() )" />
<variable name="test-arity"
select="5" />
<variable name="test-fn"
select="f:make-ref( QName( $foo-uri, 'foo:bar' ),
$test-arity )" />
<scenario label="f:arity">
<scenario label="given a proper function reference">
@ -39,32 +46,38 @@
<!-- test our format directly; do not rely on the
apply-gen code -->
<variable name="fnref"
select="f:make-ref( QName( $foo-uri, 'foo:bar' ),
$test-arity )" />
<call function="f:arity">
<param name="fnref"
select="$fnref" />
<param name="fnref" select="$test-fn" />
</call>
<expect label="provides function arity"
test="$x:result = $test-arity" />
select="$test-arity" />
</scenario>
<scenario label="given a function reference with no defined arity">
<variable name="fnref">
<f:ref><foo:bar /></f:ref>
</variable>
<scenario label="given a partially applied function reference">
<call function="f:arity">
<param name="fnref"
select="$fnref" />
select="f:apply( $test-fn, 1, 2 )" />
</call>
<expect label="returns -1"
test="$x:result = -1" />
<expect label="provides arity of the target function minus the
number of bound parameters"
select="$test-arity - 2" />
</scenario>
<scenario label="given a multiply-partially-applied function reference">
<call function="f:arity">
<param name="fnref"
select="f:apply(
f:apply( $test-fn, 1, 2 ),
3 )" />
</call>
<expect label="provides arity of the target function minus the
number of bound parameters"
select="$test-arity - 3" />
</scenario>
</scenario>
</description>