2016-11-11 60 views
0

我有下面的代碼:處理整數數據類型是否有更有效的方法?

datatype eInt = infinity of int | 0 | Int of int; 

exception undefined; 
fun eAdd(e1:eInt, 0:eInt) = e1 
    | eAdd(0, e2) = e2 
    | eAdd(e1, infinity) = infinity 
    | eAdd(infinity, e1) = infinity 
    | eAdd(infinity, ~infinity) = raise undefined 
    | eAdd(~infinity, infinity) = raise undefined 
    | eAdd(e1, e2) = e1 + e2; 

有一個新的數據類型,允許三類:無窮大,0,和INT。我認爲0在這裏可能是多餘的,但我並不確定。

我使用模式匹配來從相加兩個eInts一起制定了不同類型的可能的結果。


有四種不同的結果。

  • 如果有一個0,返回其他INT
  • 如果有一個∞,返回∞
  • 如果有一個∞和-∞,返回undefined
  • 別的,返回加兩個的他們

我能想到的唯一的事情使得這個算法更有效的是,如果我刪除重複的情況,並在年底運行(e1,e2)到(e2,e1)後再次執行該算法。

進行此更高效的任何想法?我會加入其他行動,例如分裂,這將有更多的案件。

回答

2
  1. 是,0是多餘的,因爲你也有Int 0

  2. 使用大寫構造函數名。

  3. 你有沒有你的真道由Infinity of int的意思。從你的例子來看,你只關心無窮大是積極的還是消極的,所以int也是相當多的。

  4. 而不是使用例外,請使用選項類型。

總之,你可能有

datatype IntExt = PosInf 
       | NegInf 
       | Int of int 

fun extAdd (PosInf, i2) = if i2 = NegInf then NONE else SOME PosInf 
    | extAdd (i1, PosInf) = if i1 = NegInf then NONE else SOME PosInf 
    | extAdd (NegInf, _) = SOME NegInf 
    | extAdd (_, NegInf) = SOME NegInf 
    | extAdd (Int a, Int b) = SOME (Int (a+b)) 

如果你想要一個有效的實施,考慮編碼的整數作爲IEEE 754

+0

嗨西蒙,只是想說整體感謝你。你在幫我很多,我真的很感謝你在做什麼。自從發佈以來,我修改了我的答案。我做了大部分更改,除了有更多更改。我會修改我的問題,讓其他人可以看到我現在擁有的東西。唯一的區別是,在這種情況下,我可以問一下'NONE'和'SOME'嗎? –

+0

@AndrewRaleigh:關於StackOverflow的評論並不適用於前後討論。我建議您閱讀[H&R](http://www.it.dtu.dk/introSML/)等介紹性書籍的相應部分。或者你可以谷歌周圍:[這裏](http://stackoverflow.com/questions/24980801/what-are-the-options-some-and-none-sml),[這裏](http://courses.cs .washington.edu/courses/cse341/04wi/lectures/10-ml-exceptionss.html)(最後一個資源看起來相當不錯)。 –

+0

感謝這本書,我一直在尋找一個好的:) –

1
  • 我刪除了「遞歸」標籤,因爲這個函數沒有遞歸。
  • 如果您特別擔心效率,請從最多到最不頻繁的順序排列子句。這可能意味着你的「未定義」子句將會持續下去。
  • 檢查選擇一個子句的相對效率。花費時間評估參數並切換一半時間是可能的,將會消耗較短代碼的任何節省。
+0

謝謝,我添加了標籤模式匹配,抱歉關於錯誤的標籤。不會移動未定義的下拉菜單意味着'eAdd(e1,e2)'總是會被評估嗎?我會盡力。至於第三點,這聽起來是對的。謝謝你的回答,我很欣賞它:) –

+0

哦。咄。是的,保留最後的默認條款。 OOPS! :-) – Prune

相關問題