【问题标题】:Menu variable not in scope Haskell菜单变量不在 Haskell 范围内
【发布时间】:2020-11-14 02:23:07
【问题描述】:

我正在尝试创建一个从文本文件中读取数据的菜单。但是我得到了三个错误,尽管在 IO() 开始时变量不在范围内。我没有正确阅读 txt.file,我创建菜单的方式是否错误?

错误

Variable not in scope: spaDatabase :: [Spa]

--line of error for spaDatabase
let updatedDB = (addSpa rid br ar (read st) spaDatabase)

Variable not in scope: spaDB
Variable not in scope: updatedDB :: [Spa]

--line of error for updatedDB
2 -> putStrLn (spaListStr updatedDB) >> menu spaDB

我的代码

main :: IO()
main = do 
       contents <- readFile "spa.txt"
       let spaDatabase = (read contents :: [Spa])
       menu spaDatabase
       putStrLn "" 
     where  menu spaDatabase = do
                putStrLn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" 
                putStrLn "\nPlease select an option:"
                putStrLn "1: Add a new spa to the database "       
                putStrLn "2: Show all spa "   
                putStr "\nSelected option: "
                putStrLn ""
                option <- getLine    
                putStrLn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
                
            output :: Int -> IO ()
            output option = do 
                case option of 1 -> do putStrLn "Enter Spa ID: "
                                       rid <- getLine
                                       putStrLn "Enter Spa Brand Name: "
                                       br <- getLine
                                       putStrLn "Enter Spa Area: "
                                       ar <- getLine
                                       putStrLn "Enter Spa Stars: "
                                       st <- getLine
                                       let updatedDB = (addSpa rid br ar (read st) spaDatabase)
                                       putStrLn (spaListStr updatedDB)
                                       writeFile "spa.txt" (spaListStr updatedDB)

                        
                               2 -> putStrLn (spaListStr updatedDB) >> menu spaDB
                    
   

【问题讨论】:

  • main 函数的位置定义了两个函数menuoutput。这些函数不继承do 块的范围。现在,由于 output 没有名为 spaDatabase 的参数并且范围内不存在更高的变量,因此您会收到错误消息。
  • 我建议避免使用do .. where。在do 中绑定的变量在where 中不可见。如果您只在do 中使用let,则不会出现此问题。
  • 谢谢你!虽然现在我有一个解析错误菜单 spaDatabase = do,是因为缩进吗?
  • 编辑不应使现有答案无效。我滚了回去。如果您有新问题要使用新代码提出,欢迎您发布一个新问题,说明这是此问题的后续问题,包括您认为相关的链接。 :)
  • 谢谢威尔!我设法清除了顶部错误,但它在第二选择时变成了解析错误。我会将这个链接添加到那个链接。

标签: variables haskell scope let do-notation


【解决方案1】:

where定义的一部分,而不是表达式的一部分。它属于main 的定义,因此其范围高于 do。您最初发布的代码

main = do { .....
            let c = .....
            .....
          }
       where
          a = ....
          b = ....c....
          .....

等价于

main = let {       -- where's translation
          a = ....
          b = ....c....
          .....
          }
       in
          do {
               .....
               let c = .....
               .....
             }

您在b = ....c.... 中使用c 它与let c = ..... 一起引入,即在其范围区域之外。这是一个错误,“变量不在范围内”

更新let in do blocks 只是一个捷径:

              do {
                   .....
                   let c = .....
                   .....
                 }

相同
              do {
                   .....
                   let c = .....
                   in do {
                           .....
                         }
                 }

工作代码可以结构化,就像 cmets 中提出的 @chi 一样

main = do { .....
            let c = .....
            .....
            let { a = ....
                  b = ....c....
                }
            .....
         }

这样ab 就在 c 的范围内,因此可以使用c 作为其定义的一部分。

【讨论】:

  • 对不起,什么是'in'?
  • Haskell 中let 表达式语法的一部分。
  • 抱歉,我不太了解您的代码。 a、b、c 是从哪里来的?是否存在缩进问题?
  • learnyouahaskell.com/chapters 是一个很好的介绍材料。例如learnyouahaskell.com/syntax-in-functions#let-it-be 解释 let
  • 我已经根据你的模型修改了我的代码。这是它应该看起来的样子吗?虽然我在“in”上有一个解析错误?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
  • 2017-09-30
  • 1970-01-01
  • 2022-10-08
  • 2019-10-13
相关资源
最近更新 更多