开发者

adding rectangles to list and showing rectangle

I would like to make easy program in which I could add rectangles to list (id, width, height) and show rectangle with specyfic id (id, width, height) - I think I have more than one error in below code - do You know what can be wrong ? I will run this by command 'menuRectangles' (now this doesn't work):

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 (Re开发者_StackOverflow中文版ctangle 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";


The solution is to use an accumulating list in menuRectangles.

When you call addRectangles you have to bind the result to a new variable - that is what this expression is doing:

rs_new <- addRectangle rs

Note - this is special syntax in Haskell for binding within an IO or monadic expression.

In Haskell the other binding form is let:

let xs = [2,3,4]
    ys = 1 : xs
in length ys

Here's a working version of your program - note you now have to run with main so it can seed menuRectangles with the empty list. When menuRectangles is called recursively for a menu option you have to pass on the accumulating list.

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜