mrquestion
mrquestion

Reputation: 195

check if element exists on the sub-list

I can have many Figures on my list. Each Figure can have many Rectangles on its list. I have a problem with my function checkNewRectangleId - this function should ask user about new rectangle id until he write really new id and then it should return this id - but I have an error: couldn't match expected type IO t against inferred type Maybe figureType line (Figure id width height rectangles) <- findFigure idFigure x in my function - could you help ?

import IO
import Char
import System.Exit
import Maybe
import Data.Time.Calendar
import System.Time


checkNewRectangleId :: Int -> [FigureType] -> IO Int
checkNewRectangleId idFigure x  = do
    idRectangle <- getInt "Give me new rectangle id: "
    (Figure id width height rectangles) <- findFigure idFigure x
    if isJust (findRectangle idRectangle rectangles) then do
            putStrLn ("We have yet rectangle with id " ++ show idRectangle)
            checkNewRectangleId idFigure x
        else return idRectangle


data FigureType = Figure Int Int Int [RectangleType] deriving(Show, Read)

data RectangleType = Rectangle Int CalendarTime deriving(Show, Read)

findFigure :: Int -> [FigureType] -> Maybe FigureType
findFigure _ [] = Nothing
findFigure n ((Figure id width height rectangles) : xs) =
    if n == id then Just (Figure id width height rectangles)
    else findFigure n xs

findRectangle :: Int -> [RectangleType] -> Maybe RectangleType
findRectangle _ [] = Nothing
findRectangle n ((Rectangle id date) : xs) =
    if n == id then Just (Rectangle id date)
    else findRectangle n xs

isInt i = not (null i) && all isDigit i

getInt :: String -> IO Int
getInt q = do
    putStr q;
    i <- getLine
    if isInt i == False then do
            putStrLn "Bad number"
            getInt q
        else return (read i)

Upvotes: 1

Views: 936

Answers (2)

Robin Green
Robin Green

Reputation: 33033

Since you say idFigure is guaranteed to exist, you can use fromJust in the Data.Maybe module to convert a Maybe FigureType into a FigureType:

let (Figure id width height rectangles) = fromJust $ findFigure idFigure x

Upvotes: 3

Robin Green
Robin Green

Reputation: 33033

findFigure operates in the Maybe monad, but checkNewRectangleId operates in the IO monad. Haskell will not automatically translate failures (or successes) in one monad into failures (or successes) in another, because the types don't match. So, you have to ask yourself the question, what do you want to happen if findFigure fails to find anything?

Upvotes: 1

Related Questions