2013-09-27 29 views
4

我有一個關於haskell中monad的本體論問題;我對語言是否在語句和表達之間進行區分是不穩定的。例如,我覺得像大多數其他語言一樣,像a -> SomeMonadProbs()這樣的簽名將被視爲一種聲明。這就是說,由於haskell純粹是功能性的,並且函數是由表達式組成的,所以我有點困惑於haskell對於monad表達式的描述。是monads表達式,還是Haskell中有語句?

+1

[This](http://www.haskellforall.com/2013/07/statements-vs-expressions.html)文章可能會爲您解決問題。基本上,它說一個聲明是一組處理指令,告訴計算機什麼是程序_does_,而使用表達式時,程序變成一個巨大的函數(有副作用),它告訴計算機什麼是程序_is_。除非你想進入理論層面,否則我個人不會太在乎差異。實際上,你可以編寫與之相當的程序。 – bheklilr

+0

感謝您的鏈接。大多數情況下,我認爲我只是遇到了關於「純粹功能」與大多數功能語言如erlang或scheme的概念的思想問題。 – jcc333

回答

6

這裏有一些想法。

a >>= b就像任何其他應用程序一樣是一個應用程序,所以從語法的角度來看,Haskell中顯然沒有語句,只有表達式。從語義的角度來看(例如參見Tackling the awkward squad論文),存在Haskell語義的「指稱」和「可操作」片段。

指示性片段對待>>=類似於數據構造函數,所以它認爲a >>= b在WHNF中。 「操作」片段「解構」IO monad中的值,並在此過程中執行不同的效果。

推理程序時,通常不需要考慮「操作」片段。例如,當您將foo a >> foo a重構爲let bar = foo a in bar >> bar時,您不關心foo的性質,因此IO操作與此處的任何其他值無法區分。

這是Haskell發光的地方,它很有誘惑力說沒有任何聲明,但它會導致有趣而有點矛盾的結論。例如,C預處理器語言可以被認爲是C的指稱片段。因此C也有指稱和操作片段,但沒有人說C是純粹的功能或沒有語句。詳情請見The C language is purely functional這篇文章。

當然Haskell的選自C不同定量:其指稱片段是足夠表現力是實際有用的,所以得較少考慮在其操作語義底層轉變比C.

但是,當你必須想想那些轉換,就像推理寫入網絡套接字的數據的順序一樣,你不得不求助於聲明之後的聲明。

因此,儘管IO動作本身沒有報表和一定的狹隘的技術角度有根本沒有發言,行動代表的陳述,所以我認爲這是公平地說,報表存在於哈斯克爾在一個非常間接形成。

5

的語言是否使語句和表達式之間的區別在所有

事實並非如此。在語法中沒有「語句」或類似的東西,在語言描述中沒有任何東西被稱爲「語句」或任何等同物(據我所知)。

語言報告調用do表示法中的元素「語句」。有兩種不是表達式的語句:pat <- exp`` and let decls`。在大多數與像a -> SomeMonadProbs()簽名其他語言的任何

將被視爲聲明

Haskell是從大多數其他語言不同。這就是它的意義(顯然,並不是不同,而是將表達式和語句統一到一個單一的構造中)。

+1

該報告有類似'do {stmts}' – aavogt

9

Monad只是與表達式交互的一個接口。例如,考慮這個list解析實現使do符號:

example :: [(Int, Int)] 
example = do 
    x <- [1..3] 
    y <- [4..6] 
    return (x, y) 

這desugars到:

[1..3] >>= \x -> 
[4..6] >>= \y -> 
return (x, y) 

...並在(>>=)對列表定義替代得到:

concatMap (\x -> concatMap (\y -> [(x, y)]) [4..6]) [1..3] 

重要的想法是,您可以使用do表示法做的任何事情都可以用(>>=)

的最接近在Haskell「語句」是一do符號塊的句法線,如:

x <- [1..3] 

這些線不對應於分離的表達式,但其是一種表達的,而句法片段不自足:

[1..3] >>= \x -> ... {incomplete lambda} 

所以真的更適合說,一切是在Haskell的表達,do符號給你的東西這似乎像一堆stateme的nts,但實際上desugars引擎蓋下的一堆表達。

+0

的東西所以如果我有一個類型如'IO a'的表達式,那麼理論上,Haskell認爲橡膠符合道路? – jcc333

+0

Haskell只運行你分配給'main'的任何東西。這是唯一的規則。請參閱[這裏](http://www.haskellforall.com/2013/01/introduction-to-haskell-io.html)以獲得更深入的解釋。 –

相關問題