2012-01-05 44 views
22

公式定義的函數我今天注意到,這樣的定義用不同數量的參數

是不可能的。我只是好奇這背後的(好)理由是什麼。必須有一個很好的(畢竟是Haskell :))。

注意:我不想看看上面代碼的其他實現的建議,這是一個簡單的例子來證明我的觀點。

+4

你稱之爲「安全」?讓它返回一個'Maybe'或其他東西,或者拋出一些已知的異常,或者將它用於'newtype',這個''newtype'專門用於你認爲是非退化函數的例子。 L 2希爾伯特空間(即只有定義的模空集);那將是安全的。只爲所有的'分數'實例定義'x/0 = x' _ad hoc_是非常奇怪的! - 好吧,這可能只是一個例子。 – leftaroundabout 2012-01-05 18:21:46

+0

+1哇,一直使用Haskell多年,從未注意到這樣的定義是不允許的! – is7s 2012-01-05 19:30:47

+0

@leftaroundabout'safeDivide x 0 = Nothing; safeDivide = Just。:(/)'better? :) – 2012-01-06 01:13:11

回答

25

我認爲這主要是爲了保持一致性,所以所有的子句都可以用同樣的方式閱讀,可以這麼說;即每個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定義爲!這似乎令人困惑,足以證明禁止這些條款,國際海事組織。

+0

那麼沒有更深的技術原因嗎? – aelguindy 2012-01-05 16:14:51

+1

@aelguindy:其實,是的!我已經更新了我的答案:) – ehird 2012-01-05 16:23:43

+0

感謝代碼格式編輯:),將從現在開始。我花了一段時間才弄明白爲什麼它是const(const \ bot),但現在我明白了。 – aelguindy 2012-01-05 16:31:47

11

與多個子句函數的含義由Haskell的標準(section 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 

這是這樣,函數定義/案例陳述的做事方式是好的和一致的,每一個的含義都沒有冗餘和混淆。

只有每個子句具有相同數量的參數時,這種翻譯纔有意義。當然,可能會有額外的規則來解決這個問題,但是它們會使翻譯變得複雜並且收益不大,因爲爲了讀者的緣故,您可能不希望定義類似的東西。

4

Haskell這樣做是因爲它的前身(如LML和Miranda)所做的。沒有技術上的理由,它必須是這樣的;可以擴展具有較少參數的方程。但是對於不同的方程有不同數量的參數可能是一個錯字而不是故意的,所以在這種情況下,我們禁止某些合理的東西,以在常見情況下獲得更好的錯誤報告。

相關問題