Haskell中的简单文本菜单

时间:2010-05-09 23:35:12

标签: haskell menu

我想知道创建具有下述功能的简单菜单(伪代码)的最佳解决方案是什么,就像我以前一样:

while (true) {
    x = readLine();
    case (x):
         x == "1" then do sth1 function
         x == "2" then do sth2 function
}

或者关于如何制作不符合上述模式的菜单的任何其他想法?

3 个答案:

答案 0 :(得分:10)

有一些很酷的软件包可用于构建命令行系统的高级方法:

  1. ui-command:友好命令行计划的框架
  2. haskeline:用户输入的命令行界面,用Haskell编写。
  3. HCL:用于构建命令行界面的高级库。
  4. 我特别喜欢ui-command,因为它是命令行工具的完整框架:它将分派给您为每个命令提供的处理程序函数,还为用户提供特定于命令的帮助。

    目标是一种抛光的感觉,而不是一种hackish的感觉。

答案 1 :(得分:6)

这样的东西
menu :: IO ()
menu = do
      putStrLn . unlines $ map concatNums choices
      choice <- getLine
      case validate choice of
         Just n  -> execute . read $ choice
         Nothing -> putStrLn "Please try again"

      menu
   where concatNums (i, (s, _)) = show i ++ ".) " ++ s

validate :: String -> Maybe Int
validate s = isValid (reads s)
   where isValid []            = Nothing
         isValid ((n, _):_) 
               | outOfBounds n = Nothing
               | otherwise     = Just n
         outOfBounds n = (n < 1) || (n > length choices)

choices :: [(Int, (String, IO ()))]
choices = zip [1.. ] [
   ("DoSomething", foo)
 , ("Quit", bar)
 ]

execute :: Int -> IO ()
execute n = doExec $ filter (\(i, _) -> i == n) choices
   where doExec ((_, (_,f)):_) = f

foo = undefined
bar = undefined

你可能可以在“选择”中拆分枚举,所以你只有里面的描述和功能,一点点分离,但这是有效的。评估“菜单”功能将让您选择做什么!

答案 2 :(得分:0)

这是另一个更像菜单的例子,因为它直接读取单个字符,而不需要用户按回车。

import System.IO
import System.Exit

import Control.Monad


main = forever (printMenu >> readChoice >>= menuAction)

printMenu = putStr "\np)rint 'Hello, world!'\ne)xit\nyour choice: " >> hFlush stdout

readChoice = hSetBuffering stdin NoBuffering >> hSetEcho stdin False >> getChar

menuAction 'p' = putStrLn "\nHello, world!"
menuAction 'e' = exitSuccess
menuAction _ = hPutStrLn stderr "\nInvalid choice."