1

我试图阻止我的程序在函数循环结束后停止。让我先介绍一些背景 - 在最近尝试 Haskell 失败后(这里),我一直在学习许多教程,并且能够成功地创建自己的列表,其中包含名称和优先级(下面,工作代码 - 抱歉,如果复制/粘贴错误缩进它)。

module Main where

-- Function Main, gather details, then print
main :: IO ()
main = do info <- gatherInfo
      let names = info
      putStrLn . unlines . map printDetails $ names

-- Function to Get the Info
gatherInfo :: IO [(String, Int)]
gatherInfo = do putStr "Name: "
            name <- getLine
            if name == "quit"
              then return []
              else do priority <- getPri
                      let info = (name,priority)
                      otherInfo <- gatherInfo
                      return $ info : otherInfo

 -- Function to get Priority                          
 getPri :: IO Int
 getPri = do putStr "Priority: "
        input <- getLine
        let parsed = reads input
        if parsed == []
          then do putStrLn "Incorrect Entry, please enter again"
                  getPri
          else return $ fst $ parsed !! 0


 --Function to print each detail
 printDetails :: (String, Int) -> String
 printDetails (name, priorityScore) = "Name: " ++ name ++ "Priority: " ++ show priorityScore

此代码将打印以下输出(包括用户输入):

 Patient Name: test1
 Patient Priority: 1

 Patient Name: test2
 Patient Priority: 2

 Patient Name: quit

 Patient name: test1 Priority: 1
 Patient name: test2 Priority: 2

如您所见,输入了列表项,然后在输入“退出”时代码打印列表内容。

我遇到的问题是,在输入“退出”并打印列表项时,当我重新进入程序时,这些项目已经消失了。

我想要实现的是运行gatherInfo 函数,然后打印列表(完整),然后返回gatherInfo 函数以添加另一个项目。例如,我的输出可能是这样的:

 Patient Name: test1
 Patient Priority: 1

 Patient name: test1 Priority: 1

 Patient Name: test2
 Patient Priority: 2

 Patient name: test1 Priority: 1
 Patient name: test2 Priority: 2

 Patient Name: quit (Quit program, doesn't matter what happens now)

我已经多次尝试实现这一点;例如,在每个gatherInfo 循环期间调用我的printDetails 函数来打印“信息”,但收效甚微。我怎样才能在我的设计中实现这一点?

4

1 回答 1

1

我建议您这样做:
修改您的收集信息功能,使其仅获取一名患者的信息。
然后创建另一个函数,我们称之为main':

main' patients = do patient <- gatherInfo
                    if (fst patient == "quit") 
                       then return ()
                       else do 
                               let patients' = patient:patients   -- add patient to list of patients
                               putStrLn . unlines . map printDetails $ patients' -- print list of patients
                               main' patients'  -- continue

我们在这里所做的是通过传递参数来记住程序的状态(这是在 Haskell 中完成的,因为您没有状态)。现在您的主要功能将如下所示:

main = main' []   -- start with empty list of patients

您可能会注意到,当用户输入“quit”时,我假设您的函数gatherInfo 将返回名称为“quit”的患者,但是您可以通过其他方式执行此操作

于 2013-03-26T14:56:50.637 回答