Noob question and sequence of operations (print then do something else)

I am still in an imperative way of thinking. In this example here; how would I call "putStrLn" and then set the function with a value. Eg: aa :: String -> IO () aa instr = do putStrLn "abc" putStrLn "abc" return "123" --- The error I am getting. Couldn't match expected type `()' against inferred type `[Char]' In the first argument of `return', namely `"123"' In the expression: return "123" In the expression: do putStrLn "abc" putStrLn "abc" return "123"

John Wicket wrote:
I am still in an imperative way of thinking. In this example here; how would I call "putStrLn" and then set the function with a value. Eg:
aa :: String -> IO () aa instr = do putStrLn "abc" putStrLn "abc" return "123"
--- The error I am getting.
Couldn't match expected type `()' against inferred type `[Char]' In the first argument of `return', namely `"123"' In the expression: return "123" In the expression: do putStrLn "abc" putStrLn "abc" return "123"
Your type signature is wrong. If you want an IO action whose return value is a String, say so: aa :: String -> IO String

Sorry, I was actually trying to use this as an example for something more
complicated I am trying to do. In this example, why would the inferred type
be "IO ()"
aa :: String -> String
aa instr = do
putStrLn "abc"
putStrLn "abc"
return "Az"
Couldn't match expected type `[t]' against inferred type `IO ()'
In the expression: putStrLn "abc"
In a 'do' expression: putStrLn "abc"
In the expression:
do putStrLn "abc"
putStrLn "abc"
return "Az"
On 9/24/07, Sam Hughes
John Wicket wrote:
I am still in an imperative way of thinking. In this example here; how would I call "putStrLn" and then set the function with a value. Eg:
aa :: String -> IO () aa instr = do putStrLn "abc" putStrLn "abc" return "123"
--- The error I am getting.
Couldn't match expected type `()' against inferred type `[Char]' In the first argument of `return', namely `"123"' In the expression: return "123" In the expression: do putStrLn "abc" putStrLn "abc" return "123"
Your type signature is wrong. If you want an IO action whose return value is a String, say so:
aa :: String -> IO String

John Wicket wrote:
On 9/24/07, Sam Hughes
wrote: John Wicket wrote:
I am still in an imperative way of thinking. In this example here; how would I call "putStrLn" and then set the function with a value. Eg:
aa :: String -> IO () aa instr = do putStrLn "abc" putStrLn "abc" return "123"
--- The error I am getting.
Couldn't match expected type `()' against inferred type `[Char]' In the first argument of `return', namely `"123"' In the expression: return "123" In the expression: do putStrLn "abc" putStrLn "abc" return "123" Your type signature is wrong. If you want an IO action whose return value is a String, say so:
aa :: String -> IO String
Sorry, I was actually trying to use this as an example for something more complicated I am trying to do. In this example, why would the inferred type be "IO ()"
aa :: String -> String aa instr = do putStrLn "abc" putStrLn "abc" return "Az"
Couldn't match expected type `[t]' against inferred type `IO ()' In the expression: putStrLn "abc" In a 'do' expression: putStrLn "abc" In the expression: do putStrLn "abc" putStrLn "abc" return "Az"
Ah. Because the value, putStrLn "abc", is a value of type IO (). Your problem is that you're trying to do an input/output action in a pure function. You'll need a function that returns a value of type 'IO String' (or 'IO somethingElse'). Then the do notation is used to construct actions, by chaining small actions together. Here your compiler thinks it's trying to construct a list, because do notation can be used for any monad... Note that 'return' isn't a keyword that returns from a function, it's a function that returns a value. For example, in the code foo :: IO Int foo = do print 3 return 5 return 5 is of type IO Int. That is, it's an action that 'returns' a value of type Int (when executed), so to speak. ('print 3' is an action that 'returns' a value of type (), by the way.) When you say you have aa :: String -> String, you're advertising that (aa foo) is a String. You're not advertising that it's an action that returns a String, because they're different things. do notation isn't for doing things and returning a value, it's for combining actions together into one bigger action. If you want to do things, you need your function to construct an action that does things, which means you want aa :: String -> IO String But the function 'aa' doesn't "do" things, it constructs an action.

John Wicket wrote:
Sorry, I was actually trying to use this as an example for something more complicated I am trying to do. In this example, why would the inferred type be "IO ()"
aa :: String -> String aa instr = do putStrLn "abc" putStrLn "abc" return "Az"
Couldn't match expected type `[t]' against inferred type `IO ()' In the expression: putStrLn "abc" In a 'do' expression: putStrLn "abc" In the expression: do putStrLn "abc" putStrLn "abc" return "Az"
If you change that type signature to aa :: String -> IO String then it will work. Any code that does any I/O must have a result type "IO blah". If the code returns no useful information, it will be "IO ()". If, like above, it returns a string, it will be "IO String". And so on. (I must say, that error message doesn't make it terribly clear what the problem is...)

Well aa isn't returning a string. It's returning a function for later evaluation which encapsulates the string. It's like driving anywhere in California. You can't get there following the road signs unless you've driven there once before. In this case the road signs say "return a string" but the way to get their is "return a string encapsulated in a function". The error message ("you can't get there from here") is then straightforward. -ljr Andrew Coppin wrote:
aa :: String -> String aa instr = do putStrLn "abc" putStrLn "abc" return "Az"
Couldn't match expected type `[t]' against inferred type `IO ()'
Any code that does any I/O must have a result type "IO blah". If the code returns no useful information, it will be "IO ()". If, like above, it returns a string, it will be "IO String". And so on.
(I must say, that error message doesn't make it terribly clear what the problem is...)
--
Lanny Ripple

On Mon, 24 Sep 2007, John Wicket wrote:
I am still in an imperative way of thinking. In this example here; how would I call "putStrLn" and then set the function with a value. Eg:
aa :: String -> IO () aa instr = do putStrLn "abc" putStrLn "abc" return "123"
The article http://haskell.org/hawiki/ThatAnnoyingIoType contained more information, in the good old days, when Hawiki was still running. :-(
participants (5)
-
Andrew Coppin
-
Henning Thielemann
-
John Wicket
-
Lanny Ripple
-
Sam Hughes