user266003
user266003

Reputation:

Double do and pattern matching

I have this code:

main = do
  args <- getArgs
  (var1, var2, var3, var4) <- return ("my var1", "my var2", "my var3", "my var4")    

  -- or
  -- (var1, var2, var3, var4) <- do
  --   return ("my var1", "my var2", "my var3", "my var4")  

  putStrLn "Var3 is: " ++ var3

  return ()

It doesn't do anything useful for now, though. But it doesn't work giving me the errors:

 #1
    Couldn't match expected type `[Char]' with actual type `IO ()'
    In the return type of a call of `putStrLn'
    In the first argument of `(++)', namely
      `putStrLn "Var3 is: "'
    In a stmt of a 'do' block: putStrLn "Var3 is: " ++ var3

    #2
    Couldn't match type `[]' with `IO'
    Expected type: IO Char
      Actual type: [Char]

What's interesting is if I comment out the line putStrLn "Var3 is: " ++ var3 then it compiles well.

How come? There is no additional space before putStrLn "Var3.." so it shouldn't be treated like it refers to the second "do" block.

How do I fix this?

Upvotes: 0

Views: 73

Answers (1)

Michael Rawson
Michael Rawson

Reputation: 1975

Your (major) problem is that the function application putStrLn is evaluated before the function application of (++). So what you've actually got is

(putStrLn "Var3 is: ") ++ (var3)

Which doesn't make sense, as (++) expects two strings, not a string and an I/O action. To fix this, you could place brackets around the strings:

putStrLn ("Var3 is: " ++ var3)

or use the function application operator ($):

putStrLn $ "Var3 is: " ++ var3

Upvotes: 4

Related Questions