Algo así como
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
Probablemente se podría dividir la enumeración de "opciones" para que sólo tenga las descripciones y funciones dentro de él, un poco de separación, pero esto funciona. ¡La evaluación de la función "menú" le permitirá elegir qué hacer!
tan fácil :) una pregunta más: ¿podría explicar primera línea: (putSrtln .....) Im novato en Haskell y no sé que los operadores similares. $ y así sucesivamente. Si no es un problema para ti, me ayudaría. – gruber
¡Acabo de editar mi respuesta y la hice más flexible! No probado de ninguna manera, simplemente lo escribí, pero debería ver lo que hice allí :). Sobre esa línea putStrLn: Básicamente escribí "putStrLn (unlines (map concatNums choices))" sin parantheses :) – LukeN
Bien, probado ahora, ¡funciona como un encanto! – LukeN