簡體   English   中英

函數式編程中具有緩存計算的數據類型

[英]Data Type with cached calculations in functional programming

鑒於以下 OOP 風格的示例代碼,以純功能風格獲得此行為的好方法是什么,例如在 Haskell

class P{
  private A a;
  private B b;
 
  public P(A a'){
     this.a=a';
     this.b=null;
  }
 
 public P(B b'){
     this.a = null;
     this.b = b';
 }

 public A getA(){ 
    if(this.a==null){
       //code to calculate a from b
       this.a = result;
    }
   return this.a
 } 

 public B getB(){ 
    if(this.b==null){
       //code to calculate b from a
       this.b = result;
    }
   return this.b
 } }

有兩個字段ab ,在構建 object 時,我通常只能訪問其中一個,但另一個可以從另一個計算。 一個簡單的例子是多邊形,它要么被定義為點列表的凸包,要么被定義為線列表的交點(以及多面體的更高維模擬)。 a計算b可能會非常昂貴,反之亦然,因此我不想在創建 object 時立即進行計算,而是等到實際需要時再進行計算。

我對此的一個想法是有一個記錄類型

data P = {a:: Maybe A, b:: Maybe B} 

makePA :: A -> P 
-- ...


makePB :: B -> P 
-- ...

其中兩個makePAB創建一個P 然后,每當我真正需要其中一個字段時,我可以get function,類似於上面計算字段(如果需要),然后返回兩個字段不再為Nothing的新記錄。 但這似乎過於笨拙,因為創建P需要一些計算(例如計算點的凸包),因此不能像通常那樣創建記錄。 此外,我必須通過調用get函數來封裝P在其他函數中的每次使用,以確保實際計算出該值,然后訪問該字段,我仍然必須確保它是Just A而不是Nothing由於類型是Maybe A

有沒有更好的方法來解決這個問題?

這要容易得多。 只需同時包含AB ,它們都不是可選的,並且依賴於惰性——它會自動處理所有決定是否需要計算的值。

data P = {a::A, b::B} 

calculateBfromA :: A -> B
calculateAfromB :: B -> A

makePA :: A -> P
makePA a' = P a' (calculateBfromA a')

makePB :: B -> P
makePB b' = P (calculateAfromB b') b'

你可以說,Haskell 實際上也有null值,就像 Java 一樣,但它們總是與計算正確類型的正確值的方法相關聯。 Maybe是針對實際上具有概念意義的null值,但在您的示例中,它們僅具有操作意義, Haskell 可以抽象掉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM