我今天才刚刚开始编码Haskell,停留在构建函数上,该函数从用户那里获取一个整数,将其乘以3,加一并检查是否为偶数。返回输出为布尔值,如果为偶数则返回true。 抱歉,如果代码错误,我是Haskell新手。
checkIfEven :: Int -> Bool
x <- readLn
let checkIfEven x = (even ((x*3)+1))
print checkIfEven
error:
Variable not in scope: checkIfEven :: Int -> Bool
答案 0 :(得分:5)
I / O必须在Haskell中显式处理,因为readLn
不是函数;这是一个IO动作。从真正的函数开始比较简单,该函数将要检查的值作为参数:
checkIfEven :: Int -> Bool
checkIfEven x = even (x*3 + 1)
请注意,括号不是对even
的调用的一部分,而是将表达式x * 3 + 1
“分组”,因为even x*3 + 1
被解析为(even x) * 3 + 1
。
现在我们有了一个纯函数,我们可以将其应用于用户输入的值。
program :: IO Bool
program = do
x <- readLn
return (checkIfEven (read x))
一些注意事项:
<-
不是赋值运算符;这是do
构造中的一种特殊语法,该构造从IO操作中(在这种情况下)“提取”一个值。x
将是一个字符串,因此您需要解析它以获得Int
的{{1}}值。 checkIfEven
是实现此目的的简单方法;我们忽略了用户可能输入 not 不能被解析为read
的字符串的可能性。Int
不会从函数返回值(请注意,我们没有在return
的定义中使用它。相反,它将值“提升”到新的IO操作中,具有{ {1}}必须是类型checkIfEven
的值,而不是program
。请注意,IO Bool
构造提供了一种使用IO操作的命令式外观。您可以直接使用基础功能和值。在这种情况下,我们可以简单地写
Bool
有关IO(以及一般的monad)如何工作的完整解释超出了此问题的范围;希望这将使您在进一步研究该主题时可以重点关注什么。