piggyback
piggyback

Reputation: 9264

Right type for I/O functions with argument in Haskell

I want to implement a function that asks different questions in base of sex. However I fail in giving it the right Type.

askDifferentQuestion :: String -> IO String
askDifferentQuestion sex = do
  putStrLn "ciao"

main = do
  sex <- getLine
  askDifferentQuestion sex

If I execute I get

test.hs:3:3:
    Couldn't match expected type `String' with actual type `()'
    Expected type: IO String
      Actual type: IO ()
    In the return type of a call of `putStrLn'
    In a stmt of a 'do' block: putStrLn "ciao"
Failed, modules loaded: none.

Why am I doing it wrong?

Upvotes: 1

Views: 124

Answers (2)

Greg Bacon
Greg Bacon

Reputation: 139681

The type IO String means an input/output action that yields a String when run. As is, askDifferentQuestion results in (), which usually indicates an insignificant value. This is because the only action to be run is putStrLn whose type is IO (), i.e., you run it for its side-effect only.

Assuming your type is correct, change the definition of askDifferentQuestion to both prompt the user and return the response. For example

askDifferentQuestion :: String -> IO String
askDifferentQuestion sex = putStrLn (q sex) >> getLine
  where q "M" = "What is the airspeed velocity of an unladen swallow?"
        q "F" = "How do you like me now?"
        q "N/A" = "Fuzzy Wuzzy wasn’t fuzzy, was he?"
        q "N" = "Why do fools fall in love?"
        q "Y" = "Dude, where’s my car?"
        q _ = "Why do you park on a driveway and drive on a parkway?"

Upvotes: 4

Dave L.
Dave L.

Reputation: 9801

The type of putStrLn is String -> IO () not String -> IO String.

Upvotes: 4

Related Questions