[英]Haskell IO: Couldn't match expected type `IO a0' with actual type
I am new to Haskell, and I try to understand how to do IO correctly. 我是Haskell的新手,我试着理解如何正确地执行IO。
The following works ok: 以下工作正常:
main = do
action <- cmdParser
putStrLn "Username to add to the password manager:"
username <- getLine
case action of
Add -> persist entry
where
entry = Entry username "somepassword"
Whereas the following results in compilation error: 以下结果导致编译错误:
main = do
action <- cmdParser
case action of
Add -> persist entry
where
entry = Entry promptUsername "somepassword"
promptUsername = do
putStrLn "Username to add to the password manager:"
username <- getLine
The error is here: 错误在这里:
Couldn't match expected type `IO b0' with actual type `[Char]'
Expected type: IO b0
Actual type: String
In the expression: username
[...]
What is going on here? 这里发生了什么? Why the first version works, while the second one does not?
为什么第一个版本有效,而第二个版本没有?
I know that in Stack Overflow there are a few similar questions like this, but none of them seemed to explain this problem to me. 我知道在Stack Overflow中有一些类似的问题,但是他们似乎都没有向我解释这个问题。
username
is a String
, but promptUsername
is an IO String
. username
是一个String
,但promptUsername
是一个IO String
。 You need to do something like: 你需要做一些事情:
username <- promptUsername
let entry = Entry username "somepassword"
persist entry
Here's another variant. 这是另一种变体。
main = do
action <- cmdParser
case action of
Add -> do username <- promptUsername
let entry = Entry username "somepassword"
persist entry
promptUsername :: IO String
promptUsername = do
putStrLn "Username to add to the password manager:"
getLine
-- fake definitions to make things compile
persist :: Entry -> IO ()
persist = print
cmdParser :: IO Add
cmdParser = fmap (const Add) getLine
data Add = Add deriving Show
data Entry = Entry String String deriving Show
The problem is just that promptUsername
is an action not a String. 问题是
promptUsername
是一个动作而不是String。 The action 'returns a String', so it has type IO String
, but it is itself nothing like a String. 该操作'返回一个String',因此它具有类型
IO String
,但它本身就不像String。 Since Entry xy
requires a String
in the x position, something in the shape of an action could no more fit there than a number or boolean could. 由于
Entry xy
需要x位置的String
,因此动作形状的某些东西不能比数字或布尔值更合适。 So in defining your complex action, main
, you must 'extract' the string that will result from the simpler action promptUsername
in any case of execution, and give the String
as the first argument the entry. 因此,在定义复杂动作
main
,必须“提取”在任何执行情况下由更简单的动作promptUsername
产生的String
,并将String
作为条目的第一个参数。 Then you do the persist
action on the resulting Entry
然后对生成的
Entry
执行persist
操作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.