[英]Data type with type constraint in Wadler - Essence of functional programming paper,
[英]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
} }
有兩個字段a
和b
,在構建 object 時,我通常只能訪問其中一個,但另一個可以從另一個計算。 一個簡單的例子是多邊形,它要么被定義為點列表的凸包,要么被定義為線列表的交點(以及多面體的更高維模擬)。 從a
計算b
可能會非常昂貴,反之亦然,因此我不想在創建 object 時立即進行計算,而是等到實際需要時再進行計算。
我對此的一個想法是有一個記錄類型
data P = {a:: Maybe A, b:: Maybe B}
makePA :: A -> P
-- ...
makePB :: B -> P
-- ...
其中兩個makeP
從A
或B
創建一個P
。 然后,每當我真正需要其中一個字段時,我可以get
function,類似於上面計算字段(如果需要),然后返回兩個字段不再為Nothing
的新記錄。 但這似乎過於笨拙,因為創建P
需要一些計算(例如計算點的凸包),因此不能像通常那樣創建記錄。 此外,我必須通過調用get
函數來封裝P
在其他函數中的每次使用,以確保實際計算出該值,然后訪問該字段,我仍然必須確保它是Just A
而不是Nothing
由於類型是Maybe A
。
有沒有更好的方法來解決這個問題?
這要容易得多。 只需同時包含A
和B
,它們都不是可選的,並且依賴於惰性——它會自動處理所有決定是否需要計算的值。
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.