Bobys
Bobys

Reputation: 677

Haskell Implement an IO code

Im trying to implement an IO code with this concept:

I tried this :

if input /= "y"
    then do return (username, database)
    else do putStrLn "Your vote will be modified."

but I'm getting this error:

Couldn't match expected type `()'
                with actual type `(String, Database)'
    In the first argument of `return', namely `(username, database)'
    In a stmt of a 'do' block: return (username, database)
    In the expression: do { return (username, database) }
Failed, modules loaded: none.

if run it like that:

if input /= "y"
    then do return (username, database)
    else do putStrLn "Your vote will be modified."

even if the user's input not equals to "y" the database will be updated. I can't figure out where's the problem with return (username, database)

The code is:

options 7 (username, database) = do
    putStrLn "******************"
    putStrLn "   Rate a film    "
    putStrLn "******************"
    putStrLn ""
    putStr "Enter the title of the film or nothing to return to the main menu: "
    title <- getLine
    if title == ""
        then return(username, database)
        else do
            let filmCheck = findFilm title database
            if filmCheck == []
                then do
                    putStrLn "That film does not exists."
                    return (username, database) 
                else do
                    putStr "Enter your rate: "
                    tempRate <- getLine
                    case reads tempRate :: [(Integer, String)] of
                         [(n, "")] -> do
                            let rate = read tempRate :: Int
                            let tempFilm = rateFilm username (username, rate) filmCheck
                            when (checkIfRated username tempFilm == True) $ do
                                putStrLn "You already voted for this film\n"
                                putStrLn "Do you want to modify your vote?\n"
                                putStrLn "Press y to modify or nothing to return to the main menu:"
                                input <- getLine
                                if input /= "y"
                                    then do return (username, database)
                                    else do putStrLn "Your vote will be modified."
                            let database = tempFilm:database
                            putStrLn "You rating has been  sumbited successfully!"
                            putStrLn (displayFilm tempFilm)
                            return (username, database)
                         _ -> do
                            putStrLn "The number you entered is invalid."
                            return (username, database)

Upvotes: 1

Views: 143

Answers (1)

MathematicalOrchid
MathematicalOrchid

Reputation: 62848

First, your indentation is wonky. Remember that indentation is significant in Haskell; if you get it wrong, you change the meaning of the code!

At first glance, I think the problem is here:

if input /= "y"
  then do return (username, database)
  else do putStrLn "Your vote iwll be modified."

The "do" keywords are actually redundant here. But much more importantly, putStrLn returns a (), whereas return clearly returns something else. There's your error.

As another aside, try breaking this into way, way smaller functions. This isn't Java...

Upvotes: 4

Related Questions