[Haskell-cafe] Noob question and sequence of operations (print then do something else)

Sam Hughes hughes at rpi.edu
Mon Sep 24 02:06:48 EDT 2007


John Wicket wrote:

> On 9/24/07, Sam Hughes <hughes at rpi.edu> 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.



More information about the Haskell-Cafe mailing list