3

私は最近、XSLT 1.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>

私の質問は、vFunResult変数に関係しています。$pFuncテンプレートを使用して「関数」アプリケーションを作成していることが[1]わかりますが、なぜセレクターであり、テンプレート呼び出しの arg0 が に設定されているの$pFunc[position > 0]ですか? に複数の「関数」を渡していると予想されます$pFuncfoldl?

私が見たすべての関数型プログラミングの例では、パラメーター f はリストとしてではなく単独で渡されます。この Haskell 部分関数定義: foldl f z (x:xs) = foldl f (f z x) xs

4

2 に答える 2

5

私はたまたまFXSLの著者であるため、私は「信頼できる公式」ソースであると信じています:)

私の質問は、vFunResult変数に関係しています。$pFuncテンプレートで 「関数」アプリケーションを作成していることがわかります[1]が、なぜセレクターなのか、なぜarg0 in the template call being set to $pFunc[position > 0] ? Is it expected that you are passing more than one 'function' in$pFunc tofoldl` なのか?

まず第一に、それは良い観察です。あなたは13年ぶりにこれに気づきました。

これには純粋に歴史的な理由があります。2001 年に FXSL を書いたとき、私はまだ Haskell と関数型プログラミングを学んでいました。

一部の問題では、フォールドが明らかに解決策ですが、指定する関数は 1 つの追加パラメーターを想定しています。私が言ったように、私はこれらの関数を書いたばかりで、部分適用を実装する方法をまだ理解していませんでした (これは、curry()関数を導入することによって 4 か月後に行われました。 (こちらを参照してください: http://fxsl.sourceforge.net /articles/PartialApps/Partial%20Applications.html#4._Using_currying_and_partial_application_-_the_iter_and_power_functions . ) これが、当時、そのような場合、追加のパラメーターをリストの末尾として渡すことができると判断した理由です。その最初の項目は "待望の公式」機能foldl

fxsl.sourceforge.net/articles/FuncProg/2.html#List_processing のすべての例が 1 つのテンプレートのみを渡すことに気付きました$pFunc...したがって、私の最初の考えでは、それarg0は一般に無視され$pFuncsますか?

これは正しい結論ではありません。

ここを参照してください: http://fxsl.sourceforge.net/articles/FuncProg/2.htmlminimum / maximum関数の実装方法 。彼らは、比較$arg0を実装する追加の関数が渡されることを期待しています。<したがって、これらの関数は完全に一般的なものであり、リスト内の項目のデータ型には依存しません。

とにかく、私が言ったように、質問でなされた観察は純粋な歴史的事実を反映しています. FXSL 2.0 のコードを調べると、この「機能」は完全になくなっています: http://fxsl.cvs.sourceforge.net/viewvc/fxsl/fxsl-xslt2/f/func-foldl.xsl?revision=1.3&view =マークアップ

関数は基本的に XPath 2.0 ワンライナーとして定義されます。

  <xsl:sequence select=
         "if (empty($pList))
              then 
                  $pA0
              else
                  f:foldl($pFunc, 
                          f:apply($pFunc, $pA0, $pList[1]), 
                          $pList[position() > 1]
                          )"/>

最後に、FXSL に関心をお寄せいただきありがとうございます。FXSL 2.x (XSLT 2.0 用) を見て、Extreme Markup Languages カンファレンスでの 2006 年の私の論文を読むことをお勧めします: http://conferences.idealliance.org/extreme/html/2006/Novatchev01/EML2006Novatchev01.html

XSLT 2.0 では、ほとんどの FXSL 関数を XPath 2.0 を使用してワンライナーでほぼ完全に記述することができます。

そしてもちろん、W3C XPath 3.0 仕様 ( http://www.w3.org/TR/xpath-30/#id-inline-func ) を確認する必要があります。ここでは、高次関数 (HOF) が既に完全に組み込まれています。言語の。また、Balisage 2013 カンファレンスで先月発表された私の論文「Programming in XPath 3.0」にも興味があるかもしれません。論文はこちら: http://t.co/p3mdgoTdgj

ただし、PPT プレゼンテーションはおそらくもっと興味深いものです: https://t.co/i5xCTUObvp

于 2013-09-12T03:58:21.707 に答える
3

pFuncは、foldlが追加のパラメーターを必要とする関数を適用できるようにするためのリストです。追加のパラメーターpFunc[position() > 1]は、 arg0を介してpFunc[1]で指定された関数に渡されます。

たとえば、比較関数pCMPFunを取ることができる FXSL最小関数を確認してください。これは、 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>
于 2013-09-12T03:36:20.890 に答える