XSLT FXSL foldl:函数列表?

XSLT FXSL foldl:函数列表?,xslt,fxsl,Xslt,Fxsl,最近,由于我做了一些遗留工作,我一直在学习如何在XSLT1.0中使用函数式编程结构。所以我一直在学习更多关于FXSL的知识,并且对foldl有一些疑问 <xsl:template name = "foldl" > <xsl:param name = "pFunc" select = "/.." /> <xsl:param name = "pA0" /> <xsl:param name = "pList" select =

最近,由于我做了一些遗留工作,我一直在学习如何在XSLT1.0中使用函数式编程结构。所以我一直在学习更多关于FXSL的知识,并且对foldl有一些疑问

 <xsl:template name = "foldl" >
     <xsl:param name = "pFunc" select = "/.." />
     <xsl:param name = "pA0" />
     <xsl:param name = "pList" select = "/.." />

     <xsl:choose>
         <xsl:when test = "not($pList)" >
             <xsl:copy-of select = "$pA0" />
         </xsl:when>

         <xsl:otherwise>
             <xsl:variable name = "vFunResult" >
                 <xsl:apply-templates select = "$pFunc[1]" >
                     <xsl:with-param name = "arg0" select = "$pFunc[position() > 1]" />
                     <xsl:with-param name = "arg1" select = "$pA0" />
                     <xsl:with-param name = "arg2" select = "$pList[1]" />
                 </xsl:apply-templates>
             </xsl:variable>

             <xsl:call-template name = "foldl" >
                 <xsl:with-param name = "pFunc" select = "$pFunc" />
                 <xsl:with-param name = "pList" select = "$pList[position() > 1]" />
                 <xsl:with-param name = "pA0" select = "$vFunResult" />
             </xsl:call-template>
         </xsl:otherwise>
     </xsl:choose>
 </xsl:template>

我的问题与
vfunsult
变量有关。我知道它正在用
$pFunc
模板创建一个“函数”应用程序,但是为什么
[1]
选择器,为什么模板调用中的arg0被设置为
$pFunc[position>0]
是否希望您将
$pFunc
中的多个“函数”传递给
foldl


在我所看到的所有函数式编程示例中,参数f是以单数形式传递的,而不是以列表形式传递的,这是Haskell部分函数定义:
foldl f z(x:xs)=foldl f(f z x)xs

pFunc是一个列表,因此foldl可以应用本身需要附加参数的函数。附加参数pFunc[position()>1]通过arg0传递给pFunc[1]给出的函数

例如,检查FXSL函数,它可以使用比较函数pCMPFun,然后通过pFunc[position()>1]将其传递到foldl

     <xsl:template name = "minimum" >
         <xsl:param name = "pList" select = "/.." />
         <xsl:param name = "pCMPFun" select = "/.." />

         <xsl:variable name = "vdfCMPFun" 
                       select = "document('')/*/minimum-own-compare:*[1]" />

         <xsl:variable name = "vFoldFun" 
                       select = "document('')/*/minimum-pick-smaller:*[1]" />

         <xsl:if test = "$pList" >
             <xsl:variable name = "vCMPFun" 
                           select = "$pCMPFun | $vdfCMPFun[not($pCMPFun)]" />

             <xsl:variable name = "vFuncList" >
                 <xsl:copy-of select = "$vFoldFun" /> <!-- Pick Smaller --> 
                 <xsl:copy-of select = "$vCMPFun" /> <!-- Compare --> 
             </xsl:variable>

             <xsl:call-template name = "foldl" >
                 <xsl:with-param name = "pFunc" 
                                 select = "msxsl:node-set($vFuncList)/*" />
                 <xsl:with-param name = "pList" select = "$pList" />
                 <xsl:with-param name = "pA0" select = "$pList[1]" />
             </xsl:call-template>
         </xsl:if>
     </xsl:template>

我相信我是一位“可靠的官方”消息来源,因为我碰巧是FXSL:)的作者

我的问题与
vfunsult
变量有关。我明白了 使用
$pFunc
模板制作“函数”应用程序,但为什么
[1]
选择器,为什么模板调用中的
arg0被设置为
$pFunc[位置>0]
?你是不是期望你通过的次数超过
在
$pFunc
foldl`中有一个“函数”

首先,这是一个很好的观察。你是13年来第一个注意到这一点的人

这纯粹是历史原因。2001年我写FXSL时,我还在学习Haskell和函数式编程

在某些问题中,折叠显然是解决方案,但是,我们指定的函数需要一个附加参数。正如我所说,我只是在编写这些函数,还没有弄明白如何实现部分应用程序(这是在四个月后通过引入
curry()
函数完成的。(请参见此处:)这就是为什么当时我决定在这种情况下,附加参数可以作为列表的尾部传递,列表的第一项是
foldl
期望的“官方”函数


我注意到所有的例子 fxsl.sourceforge.net/articles/FuncProg/2.html#仅用于列表处理 在
$pFunc
中传递一个模板,所以我最初的想法是
arg0
是 通常被
$pFuncs
忽略

这不是一个正确的结论

请参见此处:
最小值/最大值
函数是如何实现的。它们期望作为
$arg0
传递一个附加函数,以实现

最后,感谢您对FXSL的兴趣。我建议您阅读FXSL 2.x(用于XSLT 2.0)并阅读我2006年在极限标记语言会议上的论文:

在XSLT2.0中,可以几乎完全使用XPath2.0编写大多数FXSL函数,并将其作为一行程序

当然,您还需要了解W3C XPath 3.0规范,其中高阶函数(HOF)已经完全成为语言的一部分。您可能还对我上个月在Balisage 2013年会议上发表的论文“XPath 3.0编程”感兴趣。论文如下:


然而,PPT演示可能更有趣:

我注意到所有示例在$pFunc中只传递一个模板…所以我最初的想法是,arg0通常被$pFunc忽略了?令人惊喜的是,有像您这样的人,他们对FXSL有如此深入的了解!我非常感谢您对我们的反馈FXSL以及您需要实现的新功能。@Dimitre Novatchev:当我提交时,我很惊讶大师已经在编写答案了。感谢您创建和共享这样一个有用的库,也感谢您如此彻底地回答了这里的问题。(我想投你的赞成票,但还不能——这是我第一次这样回答。)
  <xsl:sequence select=
         "if (empty($pList))
              then 
                  $pA0
              else
                  f:foldl($pFunc, 
                          f:apply($pFunc, $pA0, $pList[1]), 
                          $pList[position() > 1]
                          )"/>