[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