0
votes

User gives: year, month, day, hour and minute and I would like to return CalendarTime value using these values. How can I do that - because I have error: 'Couldn't match expected type IO CalendarTime against inferred type Int'. What is wrong in function getDateTime ?

Proposition: all values are correct, for example month is from range 1 - 12 etc - I deleted validation from below code because otherwise code would be too long.

isInteger i = not (null i) && all isDigit i

getInteger :: String -> IO Int
getInteger q = do
    putStr q;
    i <- getLine
    if isInteger i == False then do
            putStrLn "Bad number"
            getInt q
        else return (read i)

getDateTime :: String -> IO CalendarTime
getDateTime question = do
    putStr question;
    year <- getInteger "Year: "
    month <- getInteger "Month: "
    day <- getInteger "Day: "
    hour <- getInteger "Hour: "
    minute <- getInteger "Minute: "
    return CalendarTime(year month day hour minute 0)
3
Style point: don't say "if foo == False then...."; say "if not foo then....". In this case it would be "if not $ isInteger i then..."Paul Johnson

3 Answers

4
votes

This line

return CalendarTime(year month day hour minute 0)

is read by the compiler as

return CalendarTime (year month day hour minute 0)

So it's not a call to CalendarTime. Instead you're feeding CalendarTime and (year month day hour minute 0) as arguments return. This is nonsense as return only takes a single argument and yearis not a function. You probably meant

return (CalendarTime year month day hour minute 0)

though this still doesn't work since CalendarTime requires more arguments than that. (Assuming we're talking about the one in System.Time since you didn't specify the imports).

You probably want

return $ CalendarTime { ctYear = year
                      , ctMonth = toEnum (month-1)
                      , ctDay = day
                      , ctHour = hour
                      , ctMinute = minute
                      , ctSec = 0 })

This leaves the missing fields undefined, see the relevant section in Real World Haskell for more information.

You also misspelled getInteger as getInt in the recursive call in the first function, but I'm assuming that's a result of your cleanup of the validation code.

1
votes

You don't say exactly which line gives the error, but I'm guessing the problem is:

return CalendarTime(year month day hour minute 0)

In Haskell, parentheses are used only for grouping. Function application is implicit by writing one term after the other. return should be applied to the CalendarTime value, so you probably wanted this instead:

return (CalendarTime year month day hour minute 0)

Although this would be more idiomatic:

return $ CalendarTime year month day hour minute 0
0
votes

It looks like you are trying to use the constructor CalendarTime like a function from other language styles.

return (CalendarTime year month day hour minute 0)