I /think/ I have a similar misunderstanding of the language in two places involving how variable assignment works in do blocks, involving the IO monad. Could you help me understand (1) is it the same misunderstanding, (2) how to clear it up (in an answer, and maybe specifically if you have a favorite reference on the subject)?
I find that I can perform an operation successfully when it is all one line, but not when I try to split into 2 for readability.
Part I: Turning 1 line into 2
Why does this work?
ipg :: IO ()
ipg = do
conn <- connect defaultConnectInfo { connectHost = "0.0.0.0"}
res <- execute conn "INSERT INTO test (num, data) VALUES (?, ?)" $ MyRecord (Just 200) (Just"Test")
print res
But this not work
ipg :: IO ()
ipg = do
conn <- connect defaultConnectInfo { connectHost = "0.0.0.0" }
q <- "INSERT INTO test (num, data) VALUES (?, ?)" $ MyRecord (Just 200) (Just"Test")
res <- execute conn q
print res
Gives me:
Couldn't match expected type ‘IO a0’
with actual type ‘q0 -> IO GHC.Int.Int64’
Probable cause: ‘execute’ is applied to too few arguments
In a stmt of a 'do' block: res <- execute conn q
The difference between the first and second being trying to store the query portion in q.
Part II: Turning 2 lines into 1
Why does this work:
myinput :: IO ()
myinput = do
putStrLn "Please input a number."
mynum :: Int <- readLn
print mynum
But this not work?
myinput :: IO ()
myinput = do
mynum :: Int <- readLn $ putStrLn "Please input a number."
print mynum
Gives me
Couldn't match expected type ‘IO () -> IO Int’
with actual type ‘IO a0’
The first argument of ($) takes one argument,