2011-04-22 88 views
1

我可以在我的列表中有很多数字。每个图形的列表上可以有许多矩形。我有一个问题,我的函数checkNewRectangleId - 这个函数应该问用户有关新的矩形ID,直到他写了真正的新ID,然后它应该返回这个ID - 但我有一个错误:无法匹配预期类型IO t对推断类型可能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) 

回答

3

既然你说idFigure保证存在,你可以使用fromJustData.Maybe模块中转换Maybe FigureTypeFigureType

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

thx非常! – mrquestion 2011-04-22 13:22:24

+2

在我看来,如果你已经在'let'中,那么与'Just'匹配的模式看起来比'from $''更清晰。例如'let Just(图id宽度高度矩形)= findFigure idFigure x' – 2011-04-22 15:41:33

1

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

+0

idFigure总是存在的,因为我检查之前,我调用函数checkNewRectangleId。 idRectangle不能存在,在这种情况下,程序应该再次调用checkNewRectangleId idFigure x。 – mrquestion 2011-04-22 12:32:33