我有以下代码:
doSomething :: [Int] -> [Int]
doSomething arg = arg ++ [1]
afterThreeTurns = do
first <- ["test"]
doSomething [1] -- COMMENT THIS
return first
Run Code Online (Sandbox Code Playgroud)
返回:
*Main> afterThreeTurns
["test","test"]
Run Code Online (Sandbox Code Playgroud)
如果我拿出标记为COMMENT THIS的行,则按预期返回["test"].为什么?我看待它的方式做什么应该先没有效果?
因为doSomething [1]就是[2,1],你的代码就相当于:
afterThreeTurns = do
first <- ["test"]
x <- [2,1]
return first
Run Code Online (Sandbox Code Playgroud)
这与列表理解相同,[ first | first <- ["test"], x <- [2,1] ]后者解释了为什么要获得长度为2的列表.
请注意,该变量x未在任何地方引用,因此也可以这样写:
afterThreeTurns = do
first <- ["test"]
_ <- [2,1]
return first
Run Code Online (Sandbox Code Playgroud)
这是使用IOmonad 的类似情况.代码:
thirdLine = do
getLine
getLine
x <- getLine
putStrLn $ "The third line is: " ++ x
Run Code Online (Sandbox Code Playgroud)
是相同的:
thirdLine = do
_ <- getLine
_ <- getLine
x <- getLine
putStrLn $ "The third line is: " ++ x
Run Code Online (Sandbox Code Playgroud)
您可以使用-fwarn-unused-do-bind编译器标志来获取ghc以标记这些类型的monadic语句 .在您的示例中,ghc将发出警告:
...: Warning:
A do-notation statement discarded a result of type ‘Int’
Suppress this warning by saying ‘_ <- doSomething [1]’
or by using the flag -fno-warn-unused-do-bind
Run Code Online (Sandbox Code Playgroud)