2013-04-14 169 views
4

對於參數的數據類型,Haskell函數定義中括號的含義是什麼。Haskell數據類型函數參數

例如:

doStuff Name -> Age -> String 
doStuff (NameConstr a) (AgeConstr b) = "Nom: " ++ a ++ ", age: " ++ b 

與下面定義的某事先:

data Name = NameConstr String 
data Age = AgeConstr Integer 

能函數的參數a和b在否定了括號這裏需要一種方法來捕捉?

通知你,我努力通過:

,我似乎把握只是沒有這種更精細的細節呢。

回答

7

沒有括號,函數將被視爲有四個參數。儘管如此,我想不出一個反括省略括號會導致含糊不清的反例。

如果你願意,你可以重新定義你的類型如下:

data Name = NameConstr { getName :: String } 
data Age = AgeConstr { getAge :: Integer } 

讓你的函數可以成爲:

doStuff n a = "Nom: " ++ getName n ++ ", age: " ++ show (getAge a) 

(固定的最後一部分; aInteger,不能連接到一個字符串)

4

事實上,可以根據(甚至是嵌套的)模式解析簡單的語法,而不需要parens。假設這樣一個:

<PAT> ::= <WILDCARD> | <VAR> | <CON0> | <CON1> <PAT> | <CON2> <PAT> <PAT> ... 
<VAR> ::= <LNAME> 
<CON*> ::= <UNAME> 
<WILD> ::= "_" 

其中LNAME是用小寫字母和UNAME啓動名稱以大寫字母開頭。在解析時,我們應該查看構造函數的名稱,以便我們可以找出其構造。然後我們可以使用arity信息解析構造函數字段。但是這種查找可能會使解析本身複雜化並減慢速度。 Haskell具有更復雜的模式(視圖模式,「模式,記錄,具有任意固定的中綴構造函數,e.t.c.)並省略了parens會導致模糊。

雖然還有另一個原因不這樣做。請看下面的代碼:

data Bar = Bar Int 
data Foo = Foo Int 

libFunction Foo a Bar b = a + b 
someUse bar foo = libFunction foo bar 

下一頁想象我們改變數據類型位:

data Bar = Bar 
data Foo = Foo Int Bar Int 

修改後的代碼可能仍在進行類型檢查,但功能會不會是我們期望的。儘管如此,這不是一個真實世界的例子。而且由於Haskell有類型類,所以很難找出錯誤的地方。換句話說,我們可以減少錯誤信息的質量,並且在變更後,parens可以防止我們發生意外的行爲。

+1

再加上它很難閱讀沒有parens,恕我直言 –

1

這是略帶傻氣,但在這種情況下,實際上有一種方法來避免括號:

doStuff :: Name -> Age -> String 
NameConstr a `doStuff` AgeConstr b = "Nom: " ++ a ++ ", age: " ++ b 

這正是你定義一個管道符同樣的方式,並使用反引號來綴IFY非運營商標識符在將其定義爲應用時也同樣適用。

我不推薦實際做到這一點,但你不希望在反向插入式中使用函數。