我有下面的代碼片段:瞭解做語句作爲參數
main = scotty 3000 $ do
get "/:word" $ do
beam <- param "word"
putStrLn "hello"
html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
我明白,do
聲明是如何工作的,它只是一個語法糖>>=
,但上面的例子,怎麼會這樣,那我可以通過do
塊作爲函數參數嗎?
我有下面的代碼片段:瞭解做語句作爲參數
main = scotty 3000 $ do
get "/:word" $ do
beam <- param "word"
putStrLn "hello"
html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
我明白,do
聲明是如何工作的,它只是一個語法糖>>=
,但上面的例子,怎麼會這樣,那我可以通過do
塊作爲函數參數嗎?
讓我們來定義
twice :: IO() -> IO()
twice a = do
a
a
...或短twice a = a>>a
。
你當然可以使用這個喜歡
Prelude> twice (putStrLn "hello")
hello
hello
...但Haskellers寧願節省括號,寫twice $ putStrLn "hello"
。
您還可以使用它像
Prelude> twice $ putStrLn "hello" >> putStrLn "world"
hello
world
hello
world
現在,單子序列可轉換爲一個do塊:
Prelude> twice $ do{putStrLn "hello"; putStrLn "world"}
,並與佈局而不是括號&分號,這看起來這樣的:
Prelude> :{
Prelude| twice $ do
Prelude| putStrLn "hello"
Prelude| putStrLn "world"
Prelude| :}
hello
world
hello
world
http://www.haskellforall.com/2014/10/how-to-desugar-haskell-code.html提供了幾個例子來說明w各種各樣的do
表達式是如何去除的。
單表達
do
beam <- param "word"
putStrLn "hello"
html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
首先遞歸脫糖成多個嵌套表達式:
do
beam <- param "word"
do putStrLn "hello"
html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
內一個desugars使用>>
操作者:
do
beam <- param "word"
(putStrLn "hello" >> html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"])
所得表達desugars使用>>=
:
param "word" >>= (\beam -> (putStrLn "hello" >> html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"])
這表達的是什麼,被視爲參數get "/:word"
:
main = scotty 3000 $ do
get "/:word" $ param "word" >>= (\beam -> (putStrLn "hello" >> html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"])
最後剩下do
表達平凡desugars到
main = scotty 3000 $ get "/:word" $ param "word" >>= (\beam -> (putStrLn "hello" >> html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"])
爲單行do
表達式本身就是包裹的表達式(do x = x
)。
高階函數將函數作爲函數參數 – raam86
您能更好地定義什麼讓您感到困惑嗎?你可以通過例如。 '(bar 7 + 3)'作爲一個適當類型的函數'foo'的參數。 *爲什麼*不能將'(x >> = baz z)'作爲參數傳遞給另一個適當類型的函數? –
'do'不是'>> ='本身的語法糖。 –