DMN中的函数式编程:感觉就像再次重读我的大学课程一样
在本文中,我想分享有關DMN中的遞歸支持的有趣見解,并重點介紹FEEL語言的特定屬性如何使功能編程結構能夠在DMN中建模。
我們將從一個基本的示例開始,以演示FEEL語言和DMN構造的“商業友好”性質如何使我們能夠解決一個通常不愉快的問題:遞歸函數的定義。 然后,我們將在FP土地中冒險,并且在FEEL / DMN的搖籃中,我們將欣賞功能構造最好的生物之一:Y Combinator。 最后,我們將再次被問到一個著名的問題:
使用純工程方法,讓我們立即深入研究問題!
基本遞歸示例
Drools DMN開源引擎允許在DMN商業知識模型節點中提供遞歸支持。 這使遞歸函數的建模非常容易, 這是在DMN中為遞歸函數建模時的推薦方法 :允許函數以其名稱進行調用。
讓我們看一個簡單的示例:在DMN中對階乘函數建模。
我們可以使用Kogito DMN編輯器,并如下定義DRD:
使用“事實”業務知識模型(簡稱BKM)節點以遞歸方式定義實際的階乘函數為:
我們可以注意到,該函數像其他任何普通函數一樣調用自身
遞歸函數,唯一的區別是它被定義為DMN Boxed Expression的一部分; 該函數的名稱由BKM節點使用框式表達式構造“ fac”定義,然后該函數的主體進行引用并將其自身作為FEEL表達式“ fac(n-1)”的一部分進行調用。
我們可以使用此BKM來計算輸入數據節點傳遞的實際結果,作為“計算階乘”決策的一部分,如下所示:
這可以很好地工作并給出預期的結果:
{ 我的電話:3 fac:函數fac(n) 計算階乘:6 }
關于柯里
DMN以及更重要的是FEEL語言允許定義和調用咖喱函數。
這使我們可以在FEEL中編寫如下內容:
{f:function(a)function(b)a + b,r:f(1)(2)}
哪里:
- 我們定義了一個touch:context有2個條目
- 第一個條目名為“ f”并定義了一個咖喱函數:一個參數“ a”的函數,一旦被調用,將返回一個參數“ b”的函數,一旦被調用,將返回a + b的和
- 后一個名為“ r”的條目以a = 1和b = 2調用咖喱函數。
盡管這可能是一個看起來很奇怪的FEEL表達式,但是一旦執行r = 3,我們就不會感到驚訝。
我們可以使用DMN Boxed Expression構造等效地做:
這是一個名為“咖喱和”的BKM節點; DMN可調用一個參數“ a”,一旦被調用,將返回一個參數“ b”的函數,該函數一旦被調用,將返回a + b之和。
同樣,一旦執行我們就不會感到驚訝 咖喱求和(1)(2)= 3
Y組合器:無遞歸支持的遞歸
讓我們回頭看一下前面的遞歸函數示例。 我們忽略了以下事實:在DMN中,函數實際上是否可以通過其名稱進行自身調用:DMN規范未明確支持此功能,但也未明確禁止它。 換句話說,沒有正式指定遞歸支持。
如果我們仍然需要定義遞歸函數,但又發現道路仍在建設中,缺少正式的遞歸支持,該怎么辦? 我們可以使用一種稱為“ Y Combinator ”的功能設備,該設備允許匿名函數實現遞歸,而不必依靠自身(不存在)的名稱進行自我調用。
讓我們看一個例子; 我們可以在DMN中定義Y組合器,如下所示:
它可能是一個看起來很奇怪的函數:)讓我們假設它是為我們定義的,我們可以使用它。
我們可以使用它來重新定義階乘計算,如下所示:
我們可以注意到,“ fac”函數定義的主體在總體上是相同的; 但是,它不再是一個通過名稱調用自身的函數:在函數主體中沒有任何對“ fac(…)”的調用的痕跡!
自然,仍然會有某種形式的遞歸發生,但是這次是利用閉包范圍內的參數名稱:“ f”。 結果按預期工作: fac(3)= 6
我們可以看一下另一個示例,該示例使用DMN中的Y組合器定義斐波那契序列:
我們再次注意到,在函數體中沒有對“ fib(…)”的調用,但是由于使用了Y組合器,因此可以執行斐波那契數列的遞歸計算。
再次,結果按預期工作: fib(5)= [1、2、3、5]
為了獲得更多樂趣,我們可以使用DMN Boxed Expression形式重新定義Y組合器。 這是一個有趣的練習,了解如何在其盒裝變量中應用閉包。 Y組合器的定義可以重構為:
這將再次產生相同的預期和正確結果。
對于(額外(額外的樂趣)),我們可以在單個FEEL表達式中再次重新定義Y組合器以計算例如4的階乘:
{Y:function(f)(function(x)x(x))(function(y)f(function(x)y(y)(x))),fac:Y(function(f)function(n)如果n> 1,則n * f(n-1)否則1),fac4:fac(4)} .fac4
結果不出所料:24。
結論
在本文中,我們看到了DMN中遞歸的基本示例,并且如何在引擎中利用遞歸支持非常簡單; 支持引擎遞歸支持是我們建議實現遞歸DMN的方法:給函數命名,并在函數主體中使用該名稱來調用自身。 在該示例中,我們將函數命名為“ fac”,然后在函數本身的主體中調用了“ fac(…)”。
這種方法非常實用,易于在DMN中建模,并且效果很好。
我們還看到了DMN和FEEL如何確實支持咖喱函數定義和調用。 FEEL(也是)一種功能語言; 所有這些屬性使我們能夠在DMN中定義并使用Y Combinator,這是一種無需遞歸支持即可實現遞歸的功能性設備!
我個人發現這些練習對于在DMN中應用函數式編程概念非常有趣,同時確保引擎按預期運行。 我要特別感謝我的同事Edoardo Vacchi和Luca Molteni在討論Y組合器和Currying功能時所給予的支持。
對DMN感興趣?
如果您以前不了解DMN,那么您會發現這篇文章很有趣,但是想要對DMN標準進行溫和介紹,我們提供了有關DMN的正確的崩潰課程,您可以通過以下網址免費獲得: http://learn-dmn-in-15-minutes.com
翻譯自: https://www.javacodegeeks.com/2020/04/functional-programming-in-dmn-it-feels-like-recursing-my-university-studies-again.html
總結
以上是生活随笔為你收集整理的DMN中的函数式编程:感觉就像再次重读我的大学课程一样的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聚分享qq气泡设置(QQ气泡分享)
- 下一篇: junit规则_jUnit:规则