2015-05-10 193 views
0

此代碼:這爲什麼會導致GHCI掛起?

y :: Int 
y = y + 1 

當執行時使得GHCI掛起。

y :: Int; this means y is of type Int 
y = y + 1; this means y is defined to be an Int + 1 

如果我在語句的定義中不正確,請糾正我。

爲什麼y不評價?

是因爲y被添加到一個Int中,但它只是被添加到一個類型而不是一個值?

+1

這個問題的答案http://stackoverflow.com/questions/21505192/haskell-program-outputs-loop應該是你在找什麼。 –

+0

@SimonGibbons是相同的;這是一個重複的問題。 – AJFarmar

+1

@AJFarmar:它實際上不是重複的,因爲另外一個問題是關於'<>'輸出的,特別是當ghci陷入無限循環時,它總是不會產生。 – leftaroundabout

回答

3

談到更廣泛,Haskell的文件(或GHCI)不包含的必要性/訂單列表,像其他一些編程語言。它是一種不同風格的編程語言。相反,您可以使用幾種頂級語句:

  1. 您可以定義值。 y = y + 1將符號y定義爲功能(+)對兩個其他參數y1的應用。該定義在整個文件中保存着,特別是對以上的東西的定義和以內的的定義。因此,您可以在.hs文件中完全寫入y = x + 1,然後x = 2,並要求GHCi爲y,它會說3。請注意,關鍵字let變得更加複雜,這對於定義的這種擴展性質形成了一道「牆」:let接受一個定義塊和一個值表達式,並將這些定義範圍限定在組合(定義塊,值表達式)上下文,但隔離在let以外的世界的定義。所以這也是有效的:

    Prelude> let y = x + 1; x = 2 
    Prelude> y 
    3 
    
  2. 您可以定義數據結構及其構造函數。構造函數是一個特殊的函數,我們允許參與模式匹配:換句話說,Haskell知道如何對每個構造函數進行反轉結構。你也可以定義一個type的同義詞和一個newtype,它們之間的一半。

  3. 您可以提供有關各個值(類型聲明)的元數據。這些對於縮小類型錯誤的範圍非常有幫助,因爲它們爲類型推斷算法設置了「牆」。它們也可以在增加多態性方面具有語義效果(Haskell具有「單態限制」,通常會咬傷新手),或者限制多態性爲具體類型。

  4. 可以提供關於整體包裝的元數據:雙方如何整合其他的包(import語句),以及它如何被其它軟件包(模塊語句)中使用。

這些都不是訂單是你給的哈斯克爾系統;而不是你的文件是一個模塊的所有一所大描述。同樣在一個表達式(上面的第一部分)中,您可以做的事情只有幾件事,它們通常不是必需的:您可以將值應用於其他值,創建函數,您可以創建本地定義(let)匹配(case),並且您可以在本地添加類型元數據。其他的一切,包括do符號,僅僅是一個更便捷的方式(「語法糖」)上面做這些事情。

你的兩個語句是一個類型聲明(下稱「y的由該模塊中定義的類型將是一個整數」)和定義(「來計算y由該模塊所限定,第一計算y的值,然後添加一個「)。 Haskell將它們兩個讀在一起並說:「哦,yInt,因此(+)是我知道的特定的Int-Plus操作,(+) :: Int -> Int -> Int,然後1是我知道的那個名字的具體的Int ......然後將確認類型是自洽的,併產生了一些必要的代碼,循環下去。

4

這是因爲它無限遞歸。您正在致電y,其定義爲y + 1。那麼評估將如何進行?

它是這樣的:

y 
y + 1 
(y + 1) + 1 
((y + 1) + 1) + 1 

等等...

+0

遞歸調用在哪裏? GHCI調用y調用y一次? –

+0

@ blue-sky試着想想'y'的定義? – Sibi

+1

調用y從ghci嘗試評估''y'',然後它將其視爲''y + 1'',因爲它知道''y''的定義,它會嘗試將其擴展爲''(y + 1)+ 1''等..... –

3

Haskell有沒有變數,唯一不變的,因此,你不能使用相同的風格在其他語言,以更新的值指到了最後,但它確實意味着,你可以做一些非常真棒事情,您已絆。

拿這個聲明爲例:

myList = 1 : myList 

評估後,這將涉及到自身,因而這樣做:

myList = 1 : myList      -- but I'm referring to myList, so... 
myList = 1 : (1 : myList)    -- but I'm referring to myList, so... 
myList = 1 : (1 : (1 : myList))   -- but I'm referring to myList, so... 
myList = 1 : 1 : 1 : 1 : 1 : 1...  -- etc. 

同樣爲您不斷y

y = y + 1    -- but I'm referring to y, so... 
y = y + 1 + 1   -- but I'm referring to y, so... 
y = y + 1 + 1 + 1  -- but I'm referring to y, so... 
y = 1 + 1 + 1 + 1 ... -- etc. 

GHCI不可能完全評估y的價值,因爲它是無限的,造成GHCI掛起。