检查子列表中是否存在元素

时间:2011-04-22 11:59:54

标签: haskell monads type-mismatch

我的名单上可以有很多数字。每个图可以在其列表中包含许多矩形。我的函数checkNewRectangleId有问题 - 这个函数应该向用户询问新的矩形id,直到他写出真正的新id然后它应该返回这个id - 但是我有一个错误:无法匹配预期类型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 个答案:

答案 0 :(得分:3)

由于您说idFigure保证存在,您可以使用fromJust模块中的Data.MaybeMaybe FigureType转换为FigureType

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

答案 1 :(得分:1)

findFigure在Maybe monad中运行,但checkNewRectangleId在IO monad中运行。 Haskell不会自动将一个monad中的失败(或成功)转换为另一个monad中的失败(或成功),因为类型不匹配。所以,你必须问自己一个问题,如果findFigure找不到任何东西,你想要发生什么?