[英]Are monads expressions, or are there statements in Haskell?
關於哈斯克爾的單子,我有一個本體論的問題; 我對這種語言是否區分語句和表達方式感到不滿。 例如,我覺得在大多數其他語言中,任何帶有簽名的東西a -> SomeMonadProbs ()
例如a -> SomeMonadProbs ()
都會被視為一種陳述。 也就是說,因為haskell純粹是功能性的,而且函數是由表達式組成的,所以我對於haskell在表達方面對monad所說的內容感到有點困惑。
Monad
只是一個與表達式交互的界面。 例如,考慮使用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
符號可以執行的任何do
都可以替換為對(>>=)
調用。
與Haskell中“語句”最接近的do
符號塊的語法行,例如:
x <- [1..3]
這些行不對應於孤立的表達式,而是表達式的非自包含的句法片段:
[1..3] >>= \x -> ... {incomplete lambda}
所以真的更適合說,一切是在Haskell的表達,並do
標記給你的東西這似乎像一堆報表,但實際上desugars的引擎蓋下了一堆表情。
這里有一些想法。
a >>= b
就像任何其他應用程序一樣是一個應用程序,所以從語法的角度來看,Haskell中沒有明確的語句,只有表達式。
從語義的角度來看(例如,參見解決尷尬的小隊論文),有Haskell語義的“指稱”和“可操作”片段。
指稱片段處理>>=
類似於數據構造函數,因此它認為a >>= b
在WHNF中。 “操作”片段“解構”IO monad中的值,並在該過程中執行不同的效果。
在推理程序時,通常根本不需要考慮“操作”片段。 例如,當你重構foo a >> foo a
into let bar = foo a in bar >> bar
你不關心foo
的本質,所以IO動作與這里的任何其他值都沒有區別。
這是Haskell閃耀的地方,並且很容易說沒有任何陳述,但它會導致有趣且有些矛盾的結論。 例如,C預處理器語言可以被認為是C的指稱片段。所以C也有指稱和操作片段,但是沒有人說C是純函數或沒有語句。 請參閱C語言是純粹的功能性帖子,用於詳細處理此事。
Haskell當然與C在數量上有所不同:它的指稱片段具有足夠的表現力,實際上非常有用,所以你必須考慮其操作語義中的底層轉換,而不是在C中。
但是當你必須考慮這些轉換時,比如在推理寫入網絡套接字的數據順序時,你必須采用語句后語句思維。
因此,盡管IO操作本身並不是語句,並且在某種狹隘的技術意義上根本沒有語句,但這些操作代表了語句,所以我認為可以說Haskell中的語句以非常間接的形式存在。
該語言是否完全區分語句和表達式
它不是。 在語法中沒有“語句”或類似內容的產生,在語言描述中沒有任何東西被稱為“語句”或任何等價物(據我所知)。
語言報告呼吁里面的元素do
記號“聲明”。 有兩種語句不是表達式: pat <- exp`` and
let decls`。
在大多數其他語言中,任何帶有像
a -> SomeMonadProbs ()
這樣的簽名的東西都會被視為一種陳述
Haskell與大多數其他語言不同。 這有點重要(顯然不是為了它而不同,而是將表達式和語句統一到一個構造中)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.