【问题标题】:check if element exists on the sub-list检查子列表中是否存在元素
【发布时间】:2011-04-22 11:59:53
【问题描述】:

我的清单上可以有很多数字。每个 Figure 的列表中可以有许多 Rectangles。我的函数 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)

【问题讨论】:

    标签: haskell monads type-mismatch


    【解决方案1】:

    既然你说idFigure是保证存在的,那么你可以在Data.Maybe模块中使用fromJustMaybe FigureType转换成FigureType

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

    【讨论】:

    • 在我看来,如果您已经在let 中,那么与Just 匹配的模式看起来比fromJust $ 更简洁。例如let Just (Figure id width height rectangles) = findFigure idFigure x
    【解决方案2】:

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

    【讨论】:

    • idFigure 始终存在,因为我在调用函数 checkNewRectangleId 之前对其进行了检查。 idRectangle 不能存在,在这种情况下程序应该再次调用 checkNewRectangleId idFigure x。
    猜你喜欢
    • 2021-12-17
    • 2022-01-21
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 2011-08-02
    • 2018-01-10
    • 2015-10-06
    • 1970-01-01
    相关资源
    最近更新 更多