在这个问题中,Will的回答说明了以下代码(让我们称之为code A):
reverse2lines :: IO ()
reverse2lines =
do line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
Run Code Online (Sandbox Code Playgroud)
可以转换成以下(让我们称之为code B):
reverse2lines =
do { line1 <- getLine ;
do { line2 <- getLine ;
do { putStrLn (reverse line2) ;
do { putStrLn (reverse line1) } } } }
Run Code Online (Sandbox Code Playgroud)
我很迷惑.例如,我理解这一点
addOneInt :: IO ()
addOneInt = do line <- getLine
putStrLn (show (1 + read line :: Int))
Run Code Online (Sandbox Code Playgroud)
可以转化为:
addOneInt' :: IO ()
addOneInt' = getLine >>= \line ->
putStrLn (show ( 1 + read line :: Int))
Run Code Online (Sandbox Code Playgroud)
但我不明白嵌套do转换是如何工作的.换句话说,我不明白一个人是怎么code A来的code B?管理这种转变的规则是什么?
这些规则在哪里描述/解释/指定?
有人可以用这个(转化)codeA来解释这里发生了codeB什么吗?
例如,什么do { command1; do {command2 } }意思?我该怎么解释呢?它的定义是什么?
换一种说法,
有什么区别
do {command1;command2} 和
do {command1; do {command2}} ?
此外,有什么区别
do {command1; do{command2};command3} 和
do {command1;do {command2; do {command3}}} ?
谢谢阅读.
只需将do表达式完全分开处理:嵌套它们并不会改变它们的去除方式.举个例子,我们可以从底线开始:
reverse2lines =
do { line1 <- getLine ;
do { line2 <- getLine ;
do { putStrLn (reverse line2) ;
putStrLn (reverse line1) } } }
Run Code Online (Sandbox Code Playgroud)
那么下一个:
reverse2lines =
do { line1 <- getLine ;
do { line2 <- getLine ;
putStrLn (reverse line2) >> putStrLn (reverse line1) } }
Run Code Online (Sandbox Code Playgroud)
事实上,这就像:
reverse2lines =
do { line1 <- getLine ;
do { line2 <- getLine ;
putStrLn (reverse line2)
putStrLn (reverse line1) } }
Run Code Online (Sandbox Code Playgroud)
然后我们可以将内部剩余do变为lambda:
reverse2lines =
do { line1 <- getLine ;
getLine >>= \ line2
putStrLn (reverse line2) >>
putStrLn (reverse line1) }
Run Code Online (Sandbox Code Playgroud)
然后,如果我们倒退,我们会发现它与以下相同:
reverse2lines =
do { line1 <- getLine ;
line2 <- getLine ;
putStrLn (reverse line2) ;
putStrLn (reverse line1) }
Run Code Online (Sandbox Code Playgroud)
因此,正如您通过整个示例所看到的,嵌套版本与平面版本相同.事实上,如果你只看一下desugaring do表达式的规则(我们已经看到了重要的那些),你会发现像这样嵌套它们不会改变任何东西.
事实上,这是非常自然的,因为dodesugared 的方式是递归定义的:每次我们desugar一行,我们递归跟随它的所有行,就好像它们是另一个do表达式.
| 归档时间: |
|
| 查看次数: |
1272 次 |
| 最近记录: |