无界序列 - 尾递归

问题描述 投票:0回答:1

我想创建一个无界序列,想知道是否可以通过尾递归函数来做到这一点。

一个简单的例子是

<xsl:function name="kooks:repeat" as="xs:integer*">
    <xsl:sequence select="1"/>
    <xsl:sequence select="kooks:repeat()"/>
</xsl:function>

<xsl:template match="/">
    <xsl:sequence select="kooks:repeat()[5]"/>
</xsl:template>

(我使用的是 Saxon-ee 11.4)

失败了

Severity: error
Description: class java.lang.StackOverflowError

我认为问题是因为有 2 个序列语句,然后 saxon 将其解释为追加/cons 操作,因此该函数不再是尾递归(在其模型中)。

如果我们将其与 F# 代码(我正在尝试将其转换为 XSLT)进行比较

let rec ones () =
    seq {
        yield 1
        yield! ones ()
    }

let tenMillionthEntry = 
    ones ()
    |> Seq.skip 10000000
    |> Seq.take 1
    |> Seq.head

这还不考虑连续收益率,收益率!作为函数中的操作,因此其尾递归优化有效(大概是因为此代码不会崩溃)。

xslt-3.0
1个回答
0
投票

XML slack 上的 Christian Grün 提出了如下观点:

let $inf-rec := function($start, $self) {
      map {
        'skip': function($c) { $self($start + $c, $self) },
        'take': function($c) { $start to $start + $c - 1 }
      }
    },
    $inf := function() {
      $inf-rec(1, $inf-rec)
    }
return $inf()?skip(10000000)?take(1) ! head(.)

XPath 3.1 在线示例

他还说在 XPath 4.0 中有函数 https://qt4cg.org/specifications/xpath-functions-40/Overview.html#func-do-untilhttps://qt4cg.org/specifications/xpath -functions-40/Overview.html#func-while-do 可能有帮助。

还要等待 Dimitre Novatchev 是否出现来解释他在 XPath 4 中无限序列的想法。

© www.soinside.com 2019 - 2024. All rights reserved.