IO Char 和 [Char] 之间的匹配类型错误 [英] Match type errors between IO Char and [Char]

查看:47
本文介绍了IO Char 和 [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 块,涉及putStrLngetLine.这意味着该函数必须返回某种类型的值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.

请注意,如果您为每个顶级值(此处为 isGreenmain)都包含了类型签名,那么您将从编译器中获得更多有用的信息至于错误在哪里.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆