IO Char 和 [Char] 之间的匹配类型错误 [英] Match type errors between IO Char and [Char]
问题描述
我试图从用户那里获取输入并根据输入打印出来(从 here 修改的代码):
I am trying to get input from user and print out depending on input (code modified from here):
import Data.Char (toUpper)
isGreen = do
putStrLn "Is green your favorite color?"
inpStr <- getLine
if (toUpper (head inpStr) == 'Y') then "YES" else "NO"
-- following also does not work:
-- if (toUpper (head inpStr) == 'Y') then return "YES" else return "NO"
main = do
print isGreen
但是,我收到了很多错误:
However, I am getting many errors:
testing.hs:7:44: error:
• Couldn't match type ‘[]’ with ‘IO’
Expected type: IO Char
Actual type: [Char]
• In the expression: "YES"
In a stmt of a 'do' block:
if (toUpper (head inpStr) == 'Y') then "YES" else "NO"
In the expression:
do { putStrLn "Is green your favorite color?";
inpStr <- getLine;
if (toUpper (head inpStr) == 'Y') then "YES" else "NO" }
testing.hs:7:55: error:
• Couldn't match type ‘[]’ with ‘IO’
Expected type: IO Char
Actual type: [Char]
• In the expression: "NO"
In a stmt of a 'do' block:
if (toUpper (head inpStr) == 'Y') then "YES" else "NO"
In the expression:
do { putStrLn "Is green your favorite color?";
inpStr <- getLine;
if (toUpper (head inpStr) == 'Y') then "YES" else "NO" }
testing.hs:12:5: error:
• No instance for (Show (IO Char)) arising from a use of ‘print’
• In a stmt of a 'do' block: print isGreen
In the expression: do { print isGreen }
In an equation for ‘main’: main = do { print isGreen }
问题出在哪里,如何解决?
Where is the problem and how can it be solved?
推荐答案
本质上,您的问题是将 IO
代码与非 IO 或纯"代码混淆.
Your problem is, essentially, confusing IO
code with non-IO, or "pure" code.
在isGreen
中,您有一个do
块,涉及putStrLn
和getLine
.这意味着该函数必须返回某种类型的值IO a
.您无法从中获得普通字符串",这似乎是您的意图.do
块的最后一行必须是一个 monadic 值,在这种情况下是一个 IO
值 - 所以你不能在这里简单地有一个字符串.
In isGreen
, you have a do
block involving putStrLn
and getLine
. This means the function must return a value of some type IO a
. You can't get a "plain string" from it, which seems to be your intention. The final line of the do
block must be a monadic value, in this case an IO
value - so you can't simply have a string here.
但是,您可以使用 return
函数从 String
中生成 IO String
,如注释掉的代码也不起作用":
However, you can use the return
function to make an IO String
out of a String
, as in the commented out code that "also does not work":
if (toUpper (head inpStr) == 'Y') then return "YES" else return "NO"
这工作正常,而且是必要的,就 isGreen
而言.错误是由 main
中发生的事情引起的.你不能print
一个IO
值——一个IO String
实际上不是一个字符串,它基本上是一个未来字符串的承诺",这将仅在运行时基于(在本例中)用户输入实现.
This works fine, and is necessary, as far as isGreen
is concerned. The error comes because of what happens in main
. You cannot print
an IO
value - an IO String
is not actually a string, it's basically a "promise" of a future string, that will only materialise at runtime based on (in this case) the user's input.
但是由于 main
无论如何都是 IO
操作,所以这不是问题.只需这样做:
But since main
is an IO
action anyway, this isn't a problem. Just do this instead:
main = do
isItGreen <- isGreen
print isItGreen
或者,完全等效,但更简洁,
or, completely equivalently, but imo more succinctly,
main = isGreen >>= print
您可能更喜欢 putStrLn
而不是 print
,后者在打印字符串时会包含引号.
You might prefer putStrLn
to print
, which when printing a string will include the enclosing quotes.
请注意,如果您为每个顶级值(此处为 isGreen
和 main
)都包含了类型签名,那么您将从编译器中获得更多有用的信息至于错误在哪里.
Note that, if you had included a type signature for each top level value (here isGreen
and main
), you'd have got more useful information from the compiler as to where the errors were.
这篇关于IO Char 和 [Char] 之间的匹配类型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!