28

我經常聽說Haskell沒有變量;特別是,this answer聲稱它沒有,並且至少有九次被接受。Haskell有變量嗎?

那麼它是否有變量,爲什麼?

這個問題似乎也適用於ML,F#,OCaml,Erlang,Oz,Lava以及所有中間語言的SSA

回答

47

哈斯克爾在默認情況下具有不可變的變量(在數學意義上的變量):

foo x y = x + y * 2 

默認情況下,變量不可變細胞

哈斯克爾也有可變的細胞,雖然,但你讓他們明確:

> v <- newIORef 0 
> readIORef v 
0 

> writeIORef v 7 
> readIORef v 
7 

所以,YES Haskell有真正的變量。但它默認不使用可變變量。

4

是的,Haskell有變量。考慮(基本上等效)定義

inc n = n + 1 
inc = \n -> n + 1 

在這兩種情況,n是一個變量;它會在不同的時間呈現不同的價值。 Haskell ReportSection 3將這些明確地稱爲變量。

n這裏是一個變量可以更容易地看到,如果我們考慮下面的完整的程序:當然

inc n = n + 1 
f = inc 0 
g = inc 1 
main = print (f+g) 

打印的答案將是「3」。在評估f時,由於我們展開inc,因此x將取值0,並且當後面(或更早!)評估g時,我們展開incx將取值1

可能會出現一些混淆,因爲與問題中列出的其他語言一樣,Haskell是單指派語言:它不允許在範圍內重新分配變量。一旦n已被分配值42,它不能是任何東西,但不會引入新的範圍與新的n(這是一個不同的變量,其他值n)綁定到另一個值。

使用do這可能不是在某些情況下,如表情完全是顯而易見的:

do let n = 1 
    print n 
    let n = 2 
    print n 

,但如果你刪除的語法糖,將其轉化爲哈斯克爾沒有do,很明顯,有一個創建了新的,嵌套的範圍,其中在該內範圍n是一個不同的變量,其在外部範圍遮蔽的n

(let n = 1 
    in (print n >> (let n = 2 
        in print n))) 
+1

有Haskell中沒有變量!變量可能會被重新分配。你有什麼功能或讓-綁定只不過是不可改變的功能參數,這是一個與名稱綁定的值! – Dario 2009-06-14 16:56:38

+6

達里奧,維基百科不同意,列出了九種語言,其中所有變量均爲單一賦值,另有五種單一賦值爲選項:http://en.wikipedia.org/wiki/ Single_assignment。此外,提出該術語的數學家也使用單賦值意義上的變量。如果您要反駁這個問題,那麼發佈一個詳細答案,說明爲什麼這是錯誤的視圖? – 2009-06-14 17:09:54

3

「我聽說Haskell沒有變量。 ?這是真的」。

No

「所以它有變量或沒有,以及爲什麼」

Yes.

編輯:?我的回答使雙負,這是自然混亂,因爲標題問題是積極的,而身體不是。:)

編輯2:再次編輯,因爲OP改變了問題。

8

簡單的答案是:是的,Haskell的變量如Section 3.2 of the Haskell Report中定義。變量可以出現在模式中,因此可以使用構造如let,case和列表解析來綁定到值。

也許你的問題隱含的是,如果一個變量是不可變的,那麼它是否被正確地稱爲變量。我認爲其他答案足以涵蓋可變性。

3

根據[維基百科(http://en.wikipedia.org/wiki/Variable_(programming)),是的,Haskell有變量:鏈接到存儲在系統的存儲器中的值

在計算機程序中,變量是一個標識符(通常是字母或字)或可被計算的表達式,例如,一個可變可能被稱爲「TOTAL_COUNT」和包含一個數字。
在命令性編程語言中,值一般可以在任何時間被訪問或改變。然而,在純函數和邏輯語言,變量綁定到表達式並在其中保持單個值由於參照透明度的要求,整個生命週期。在命令式語言中,常量表現出相同的行爲,通常與正常變量相對照。

當然,並非所有的維基百科定義都是完全可信的。

上[數學變量]頁(http://en.wikipedia.org/wiki/Variable_(mathematics))可以提供進一步的深入瞭解這一點。