简单函数错误“变量不在范围内” haskell

-2 haskell

我今天才刚刚开始编码Haskell,停留在构建函数上,该函数从用户那里获取一个整数,将其乘以3,加一并检查它是否为Even。返回输出为布尔值,如果为偶数则返回true。抱歉,如果代码错误,我是Haskell新手。

checkIfEven :: Int -> Bool
x <- readLn
let checkIfEven x = (even ((x*3)+1))
print checkIfEven   

 error:
    Variable not in scope: checkIfEven :: Int -> Bool
Run Code Online (Sandbox Code Playgroud)

che*_*ner 5

I / O必须在Haskell中显式处理,而readLn不是函数。这是一个IO动作。从将要检查的值作为参数的true函数开始比较简单:

checkIfEven :: Int -> Bool
checkIfEven x = even (x*3 + 1)
Run Code Online (Sandbox Code Playgroud)

请注意,括号不是对的调用的一部分even,而是将表达式“分组”为x * 3 + 1even x*3 + 1解析为(even x) * 3 + 1

现在我们有了一个纯函数,我们可以将其应用于用户输入的值。

program :: IO Bool
program = do
    x <- readLn
    return (checkIfEven (read x))
Run Code Online (Sandbox Code Playgroud)

注意事项:

  1. <-不是赋值运算符;这是在do结构中的特殊语法,该结构从IO操作中(在此上下文中)“提取”一个值。
  2. x将是一个字符串,因此您需要对其进行解析以获取的IntcheckIfEvenread是这样做的简单方法;我们忽略了用户可能输入无法解析为的字符串的可能性Int
  3. return不会从函数返回值(请注意,我们没有在。的定义中使用它checkIfEven。而是将值“提升”到新的IO操作中,必须program是type的值IO Bool,而不是Bool

请注意,do构造提供了一种使用IO操作的命令式方法。您可以直接使用基础功能和值。在这种情况下,我们可以简单地写

program = fmap (checkIfEven . read) readLn
Run Code Online (Sandbox Code Playgroud)

有关IO(通常是monad)如何工作的完整解释超出了此问题的范围;希望这将使您在进一步研究该主题时可以重点关注什么。