为什么我不能使用 (cnt <- hGetContents h) 表达式而不是 cnt?
Why I can't use the (cnt <- hGetContents h) expression instead of cnt?
我学Haskell。它工作正常:
import System.IO
main = do
h <- openFile "text.txt" ReadMode
cnt <- hGetContents h
mapM_ putStrLn $ lines cnt
hClose h
但这不起作用:
import System.IO
main = do
h <- openFile "text.txt" ReadMode
mapM_ putStrLn $ lines (cnt <- hGetContents h)
hClose h
为什么我的第二个变体不起作用?我希望这两个变体是相等的,因为 (cnt <- hGetContents h)
是一个表达式,而 returns 也是一个值。
问题是cnt <- hGetContents h
不是一个表达式,它是do notation里面的一些特殊语法糖。这意味着它是编写以下正常 Haskell 代码的不同方式:
hGetContents h >>= \ cnt -> {- rest of do block -}
{- rest of the do block -}
之前的部分在这里不是一个完整的表达式,因为需要 do 块的其余部分来完成 lambda 的主体。
您可以手动将其脱糖以获得如下内容:
hGetContents h >>= \ cnt -> mapM_ putStrLn (lines cnt)
或免积分版
hGetContents h >>= mapM_ putStrLn . lines
您可以看出它是一个特殊的表达式,因为它引入了一个新的标识符 (cnt
),您可以在表达式本身之外的其余代码中使用该标识符。这不是普通 Haskell 表达式可以做的事情(至少没有编译时魔术)。
cnt <- hGetContents h
本质上是 hGetContents h >>= \cnt ->
.
的语法糖
它不是一个表达式,它是用于 do 块中它自己的行的糖。
如果您仍想将它保留在一行中,您可以这样做,但您以后将无法引用该文件的内容:
import System.IO
main = do
h <- openFile "text.txt" ReadMode
hGetContents h >>= mapM_ putStrLn . lines
hClose h
我学Haskell。它工作正常:
import System.IO
main = do
h <- openFile "text.txt" ReadMode
cnt <- hGetContents h
mapM_ putStrLn $ lines cnt
hClose h
但这不起作用:
import System.IO
main = do
h <- openFile "text.txt" ReadMode
mapM_ putStrLn $ lines (cnt <- hGetContents h)
hClose h
为什么我的第二个变体不起作用?我希望这两个变体是相等的,因为 (cnt <- hGetContents h)
是一个表达式,而 returns 也是一个值。
问题是cnt <- hGetContents h
不是一个表达式,它是do notation里面的一些特殊语法糖。这意味着它是编写以下正常 Haskell 代码的不同方式:
hGetContents h >>= \ cnt -> {- rest of do block -}
{- rest of the do block -}
之前的部分在这里不是一个完整的表达式,因为需要 do 块的其余部分来完成 lambda 的主体。
您可以手动将其脱糖以获得如下内容:
hGetContents h >>= \ cnt -> mapM_ putStrLn (lines cnt)
或免积分版
hGetContents h >>= mapM_ putStrLn . lines
您可以看出它是一个特殊的表达式,因为它引入了一个新的标识符 (cnt
),您可以在表达式本身之外的其余代码中使用该标识符。这不是普通 Haskell 表达式可以做的事情(至少没有编译时魔术)。
cnt <- hGetContents h
本质上是 hGetContents h >>= \cnt ->
.
它不是一个表达式,它是用于 do 块中它自己的行的糖。
如果您仍想将它保留在一行中,您可以这样做,但您以后将无法引用该文件的内容:
import System.IO
main = do
h <- openFile "text.txt" ReadMode
hGetContents h >>= mapM_ putStrLn . lines
hClose h