проверить, существует ли элемент в подсписке - PullRequest
1 голос
/ 22 апреля 2011

У меня может быть много цифр в моем списке. Каждая фигура может иметь много прямоугольников в своем списке. У меня проблема с моей функцией checkNewRectangleId - эта функция должна спрашивать пользователя о новом идентификаторе прямоугольника, пока он не напишет действительно новый идентификатор, а затем должна вернуть этот идентификатор - но у меня есть ошибка: не удалось сопоставить ожидаемый тип IO t с предполагаемым типом Maybe Линия figureType (Figure id width height rectangles) <- findFigure idFigure x в моей функции - не могли бы вы помочь?

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)

Ответы [ 2 ]

3 голосов
/ 22 апреля 2011

Поскольку вы говорите, что idFigure гарантированно существует, вы можете использовать fromJust в модуле Data.Maybe для преобразования Maybe FigureType в FigureType:

let (Figure id width height rectangles) = fromJust $ findFigure idFigure x
1 голос
/ 22 апреля 2011

findFigure работает в монаде Maybe, но checkNewRectangleId работает в монаде IO. Haskell не будет автоматически переводить неудачи (или успехи) в одной монаде в неудачи (или успехи) в другой, потому что типы не совпадают. Итак, вы должны задать себе вопрос: что вы хотите, чтобы произошло, если findFigure ничего не может найти?

...