3 回答

TA貢獻1909條經驗 獲得超7個贊
我認為這主要是為了保持一致性,以便可以以相同的方式讀取所有子句;可以這么說。也就是說,每個RHS在功能類型中都位于相同的位置。如果您允許的話,我認為也會掩蓋很多愚蠢的錯誤。
還有一個語義上的怪癖:說編譯器填充了這些子句,使其具有與其他子句相同數量的模式;即你的例子將成為
safeDivide x 0 = x
safeDivide x y = (/) x y
現在考慮第二行是否改為safeDivide = undefined;在沒有上一個子句的情況下,safeDivide它將是⊥,但是由于此處執行了eta擴展,所以它是\x y -> if y == 0 then x else ⊥-因此safeDivide = undefined實際上并沒有定義safeDivide為⊥!國際海事組織,這似乎足以使人們有理由禁止此類條款。

TA貢獻1827條經驗 獲得超4個贊
具有多個子句的函數的含義由Haskell標準(第4.4.3.1節)通過轉換為lambda和case語句來定義:
fn pat1a pat1b = r1
fn pat2a pat2b = r2
變成
fn = \a b -> case (a,b) of
(pat1a, pat1b) -> r1
(pat2a, pat2b) -> r2
這樣一來,函數定義/ case語句的處理方式就很好并且保持一致,并且沒有多余地且混亂地指定每個函數的含義。
僅當每個子句具有相同數量的參數時,這種翻譯才真正有意義。當然,可能會有其他規則來解決此問題,但是它們會使翻譯復雜化,但收效甚微,因為您可能不想為了讀者的利益而定義這樣的內容。

TA貢獻2036條經驗 獲得超8個贊
Haskell之所以這樣做,是因為它的前輩(如LML和Miranda)做到了。沒有技術原因必須如此。具有較少參數的方程式可以進行eta展開。但是對于不同的方程式使用不同數量的參數可能是一種錯字而不是有意的,因此在這種情況下,我們禁止在某些情況下明智且罕見的做法,以便在常見情況下獲得更好的錯誤報告。
添加回答
舉報