我想制作一个简单的程序,我可以在其中添加矩形到列表(id,width,height)并显示带有specyfic id(id,width,height)的矩形 - 我想我在下面的代码中有多个错误 - 你知道什么是错的吗?我将通过命令'menuRectangles'来运行它(现在这不起作用):
import IO
import Char
menuRectangles = do
putStrLn "Please choose option:"
putStrLn "1 - Add rectangle"
putStrLn "2 - Show rectangle"
putStrLn "3 - Quit"
putStr "Number: ";
n <- getLine
case n of
"1" -> do addRectangle; menuRectangles;
"2" -> do showRectangle; menuRectangles;
"3" -> menuRectangles;
otherwise -> putStrLn "The End";
addRectangle = do
putStrLn "Id: "
id <- getLine
putStrLn "Width: "
width <- getLine
putStrLn "Height: "
height <- getLine
addingRectangle (Rectangle id width height);
showRectangle = do
putStrLn "Choose id rectangle: "
id <- getLine
showingRectangle r[id];
data RectangleType = Rectangle Int Int Int deriving(Show)
addingRectangle r [] = [r]
addingRectangle r rx = r:rx
showingRectangle (Rectangle id width height) = "id: " ++ show id ++ "width: " ++ show width ++ "height: " ++ height ++ "\n";
答案 0 :(得分:1)
解决方案是使用menuRectangles
中的累积列表。
当你调用addRectangles
时,你必须将结果绑定到一个新变量 - 这就是这个表达式正在做的事情:
rs_new <- addRectangle rs
注意 - 这是Haskell中用于在IO或monadic表达式中进行绑定的特殊语法。
在Haskell中,另一种绑定形式是let
:
let xs = [2,3,4]
ys = 1 : xs
in length ys
这是您的程序的工作版本 - 请注意,您现在必须使用main
运行,以便它可以使用空列表来menuRectangles
种子。当递归调用menuRectangles
菜单选项时,你必须传递累积列表。
import IO
import Char
main :: IO ()
main = do
xs <- menuRectangles []
mapM print xs
return ()
-- A new helper - this will throw an error
-- if you don't type a number. There are
-- plenty of ways to make it more robust.
--
getInt :: IO Int
getInt = do
xs <- getLine
return (read xs)
menuRectangles :: [RectangleType] -> IO [RectangleType]
menuRectangles rs = do
putStrLn "Please choose option:"
putStrLn "1 - Add rectangle"
putStrLn "2 - Show rectangle"
putStrLn "3 - Quit"
putStr "Number: "
n <- getLine
case n of
"1" -> do { rs_new <- addRectangle rs; menuRectangles rs_new };
"2" -> do { showRectangle rs; menuRectangles rs }
"3" -> do { putStrLn "Quitting"; return rs }
otherwise -> do { putStrLn "The End"; return rs }
addRectangle :: [RectangleType] -> IO [RectangleType]
addRectangle rs = do
putStrLn "Id: "
id <- getInt
putStrLn "Width: "
width <- getInt
putStrLn "Height: "
height <- getInt
let new_rs = addingRectangle (Rectangle id width height) rs
return new_rs
showRectangle :: [RectangleType] -> IO ()
showRectangle rs = do
putStrLn "Choose id rectangle: "
id <- getInt
-- Need a lookup
case findRectangle id rs of
Nothing -> putStrLn ("Not found " ++ show id)
Just rect1 -> putStrLn (showingRectangle rect1)
data RectangleType = Rectangle Int Int Int deriving(Show)
addingRectangle :: RectangleType -> [RectangleType] -> [RectangleType]
addingRectangle r [] = [r]
addingRectangle r rx = r:rx
showingRectangle :: RectangleType -> String
showingRectangle (Rectangle id width height) =
"id: " ++ show id ++ "width: " ++ show width ++
"height: " ++ show height ++ "\n";
-- We have to use Maybe - Just rectangle OR Nothing
-- to account for the case where the id does not match
--
findRectangle :: Int -> [RectangleType] -> Maybe RectangleType
findRectangle _ [] = Nothing
findRectangle n ((Rectangle i w h):xs) =
if n == i then Just (Rectangle i w h) else findRectangle n xs