2011-04-22 3 views
1

В моем списке может быть много цифр. Каждая фигура может иметь много прямоугольников в своем списке. У меня проблема с моей функцией checkNewRectangleId - эта функция должна запрашивать у пользователя новый идентификатор прямоугольника до тех пор, пока он не напишет действительно новый идентификатор, а затем он должен вернуть этот идентификатор, - но у меня есть ошибка: не удалось сопоставить ожидаемый тип IO t с предполагаемым типом Возможно figureType line (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) 

ответ

3

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

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

thx очень много! – mrquestion

+2

На мой взгляд, если вы уже находитесь в 'let', то шаблон, совпадающий с' Just', выглядит более чистым, чем 'fromJust $'. Например, 'let Just (прямоугольные прямоугольники ширины ID) = findFigure idFigure x' –

1

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

+0

idFigure всегда существует потому, что я проверить его, прежде чем я вызвать функцию checkNewRectangleId. idRectangle не может существовать, и в этой ситуации программа должна снова вызвать checkNewRectangleId idFigure x. – mrquestion

Смежные вопросы