Haskell结束循环返回

问题描述:

我试图阻止我的程序在函数循环结束后停止。让我先给出一些背景 - 在Haskell最近失败的尝试(Here)后,我一直在通过大量的教程,并已成功地创建了包含名称和优先级的自己的列表(下面,工作代码 - 道歉,如果复制/粘贴错过了它)。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函数来打印'info',但收效甚微。我怎样才能实现这个到我的设计?

+1

难道你不能只在main的最后一行调用main来使程序再次运行吗? – DiegoNolan 2013-03-26 14:51:42

+0

你想让数据在程序的调用之间持续存在吗? – pat 2013-03-26 15:00:51

+0

@pat是否意味着,数据保持在重新启动程序之间? – ZeeeeeV 2013-03-26 15:15:57

我建议你这样做:
修改你的收集信息功能,以便它只需要一个病人的信息。
然后创建另一个函数,我们称之为主:

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 

您可能注意到,我认为你的函数gatherInfo将名称返回病人“跳槽”当用户输入“跳槽”,但你可以做一些其他的方式

+1

您不能通过'(:)' – pat 2013-03-26 14:59:17

+0

@pat修正列表末尾添加'patient',谢谢 – Martinsos 2013-03-26 15:02:34

+0

这个修改似乎给了我一个输入'putStrLn'错误的解析错误。我会尽力调查更多。 – ZeeeeeV 2013-03-26 15:33:32