我发现只要一行就可以成功执行操作,但是当我为了便于阅读而尝试拆分为2时,我不能。
第一部分:将1行变为2
为什么这样做?
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
但这不起作用
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
给我:
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
第一个和第二个尝试将查询部分存储在q中的区别。
第二部分:将2行转为1
为什么这样做:
myinput :: IO ()
myinput = do
putStrLn "Please input a number."
mynum :: Int <- readLn
print mynum
但这不起作用?
myinput :: IO ()
myinput = do
mynum :: Int <- readLn $ putStrLn "Please input a number."
print mynum
给我
Couldn't match expected type ‘IO () -> IO Int’
with actual type ‘IO a0’
The first argument of ($) takes one argument,
答案 0 :(得分:4)
在
execute conn "INSERT INTO test (num, data) VALUES (?, ?)" $ MyRecord (Just 200) (Just "Test")
,$
运算符的左侧是execute conn "INSERT…"
,右侧是MyRecord …
。也就是说,您使用三个参数调用execute
:连接,查询和参数。这是第一个问题:
q <- "INSERT INTO test (num, data) VALUES (?, ?)" $ MyRecord (Just 200) (Just "Test")
res <- execute conn q
此处,$
运算符的左侧是字符串"INSERT…"
,右侧是参数。您正在尝试调用字符串,然后将结果作为第二个参数传递给execute
。
如果q
可能是一个代表两个参数的奇怪类型,那么它可能不是IO a
。您只想使用let
命名一个值,而不是执行操作。
这应该有效:
ipg :: IO ()
ipg = do
conn <- connect defaultConnectInfo { connectHost = "0.0.0.0" }
let query = "INSERT INTO test (num, data) VALUES (?, ?)"
let parameters = MyRecord (Just 200) (Just "Test")
res <- execute conn query parameters
print res
myinput :: IO ()
myinput = do
mynum :: Int <- readLn $ putStrLn "Please input a number."
print mynum
这个没有多大意义。也许这是对$
运营商的误解? $
主要是一种不使用括号来编写表达式的方法; f $ x
相当于f x
,但$
的优先级较低,因此您可以写f $ 1 + 2
而不是f (1 + 2)
。
无论如何,如果有帮助的话,我会松散地将它翻译成Python:
def myinput():
mynum = int(input(print("Please input a number.")))
print(mynum)
如果您想对readLn
和putStrLn
操作进行排序,可以使用>>
运算符(这是do
在幕后执行的操作):
myinput :: IO ()
myinput = do
mynum :: Int <- putStrLn "Please input a number." >> readLn
print mynum
但是,大多数时候,这对于可读性来说并不是很好。 (a >> b
也会在没有投诉的情况下放弃a
的结果,而如果丢弃不是do { a; b }
的内容,()
会给编译器发出警告。)