7

當我在Haskell中寫入類似map (1+) list的東西時,(1+)的內部表示是什麼?由於它是(+)的部分應用,所以參數1必須保存在某個地方,但我無法理解這一點。有人可以給我一個簡單的解釋,如何實施咖啡和部分應用?部分應用程序在運行時如何表示?

+0

您是否瞭解關閉(如何實現lambda函數)? '(1+)'只是說'(\ x - > 1 + x)'的簡短方式。 – 2011-04-03 18:36:20

+0

是的。但是我想知道,編譯器如何將類似的東西翻譯成機器代碼/無論如何。 – fuz 2011-04-03 18:37:27

+1

如果你對這些東西感興趣,我強烈建議你閱讀[PLAI](http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/2007-04-26/)。雖然它是Scheme而不是Haskell,但核心思想是一樣的。尤其請參閱第8章:實現Laizness並注意他們如何處理'closureV'值類型。 – 2011-04-04 04:58:33

回答

2

您可能還想看看Implementing Functional Languages: A Tutorial,一本由Simon Peyton Jones和David Lester編寫的書。

+0

我在哪裏可以得到它? – fuz 2011-04-04 17:10:37

+0

不知道。幾年前我從當地的大學圖書館借了它,但我不認爲這是一種選擇。 無論如何,如果你能掌握它,我強烈建議你這樣做。這是一個非常輕量級的文本,也是功能語言實現的非常好的介紹。 – 2011-04-04 17:16:05

+1

現在看起來有一個在線版本,該書已絕版:http://research.microsoft.com/en-us/um/people/simonpj/Papers/pj-lester-book/ – 2011-04-04 17:18:17

6

想想這樣:所有的東西都是由一段代碼(一個「thunk」)表示的,必須直接調用才能得到結果。當你編寫一個文字1時,它會被編譯成一個調用時返回1的代碼塊(實際上是fromIntegral 1),然後代碼塊被用來代替文字1.這也是懶惰的關鍵:代替立即計算某個東西,創建一個thunk,在調用時將執行計算。如果將該表達式傳遞給另一個函數,那麼它就是傳遞的包裝器thunk,所以直到/除非需要明確檢查其結果,否則計算不會發生。

在Haskell中,函數應用程序以相同的方式表示:一個thunk處理一個參數並返回一個thunk,該thunk處理下一個參數或產生結果。所以(1+)是功能應用程序(+) 1(+)是一個thunk,希望傳遞一個單一的數字並返回一個thunk,期望通過另一個單一的數字。由於(+)是嚴格的,那第二個thunk實際上做了加法,而不是返回一個必須被調用來執行實際加法的thunk。因此(1+)評估爲第二個thunk,需要用map提供的另一個數字調用,因爲它在list上迭代。

+0

這是做到這一點的一種方式,但它絕不是唯一的方法。 – augustss 2011-04-03 23:09:46

+1

@augustss:因此「用這種方式思考」。 – geekosaur 2011-04-03 23:13:06

9

部分應用函數(實際上幾乎所有Haskell堆中的其他東西)都被表示爲閉包 - 一個結合了代碼指針和參數槽的結構。具體而言,我們將未完全評估的值稱爲thunks

boxed data上查看此早期問題,並在how thunks are represented上查看GHC手冊。

+0

啓發。謝謝! – fuz 2011-04-04 12:48:33

相關問題