为什么这个变量在where中是不可见的

Why this variable is invisible in where

我想从文本文件中读取一个矩阵 [[Int]](这个矩阵在 a project euler's problem), 所以我有下面的代码

parseInt :: String -> [Int]
parseInt [] = []
parseInt (x : xs) = [(ord x) - (ord '0')] ++ (parseInt xs)

main = do
  str <- readFile "11.dat" 
  print $ fmap parseInt (lines str)

此代码运行良好,我可以读取矩阵输出。

但是,我想更改 main 函数,这样我就可以重用 fmap parseInt (lines str) 而不是在我的代码中重复它。

main = do
  str <- readFile "11.dat" 
  print b
  where b = fmap parseInt (lines str)

编译器报错

11.hs:37:34: error:
    Variable not in scope: str :: String
[Finished in 0.9s]

似乎是 feed 操作 str <- readFile "11.dat" 导致了这个问题,因为当我直接从字符串读取代码时,代码工作正常

main = do
  print b
  where b = fmap parseInt (lines "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08\n...01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48\n")

我也可以 let

main = do
  str <- readFile "11.dat" 
  let b = fmap parseInt (lines str)
  print b

那么我怎样才能用 that

这是一个解析问题。 Haskell 将违规代码解析为

main = (do {str <- readFile "11.dat"; print b}) where {b = fmap parseInt (lines str)}

因此 where 子句范围内的唯一局部变量是 = 左侧的模式变量(全部 none,但通常,您可能有一些)。

与此同时,str 范围仅从其绑定到 do 块的末尾。这就是为什么在绑定后将 let 放在 do 块中就可以正常工作的原因。