读取字符串并测试它是否是数字
为什么这段代码不起作用?如果字符串是数字,我想返回 Bool。
isNumber = do
n <- getLine
let val = case reads n of
((v,_):_) -> True
_ -> False
Why this code doesn't work ? I would like to return Bool if string is a number.
isNumber = do
n <- getLine
let val = case reads n of
((v,_):_) -> True
_ -> False
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您有一个语法错误:
因为您的函数尚未返回值。修复:
现在它在语法上是正确的,但有一个类型错误:
为什么?因为
read
已经超载了。因此编译器不知道您要读取的内容。在本例中,您正在尝试读取一个数字。假设是一个Integer
:尽管如此,它并不是很惯用。让我们将 IO 与纯代码分开,如果成功的话,实际上返回解析的数字:
测试:
所以我们已经清理了解析,并将 IO 与解析分开,这意味着您可以单独测试解析器,并添加类型信息记录您的设计。
Firstly, you have a syntax error:
Because your function doesn't return a value yet. Fixing that:
Now it is syntactically correct, but it has a type error:
Why? Because
read
is overloaded. So the compiler doesn't know what you're trying to read. In this case, you're trying to read a number. Let's say, anInteger
:Still, its not really idiomatic. Let's separate the IO from the pure code, and actually return the parsed number, if it succeeds:
Testing:
So we've cleaned up the parsing, and separted IO from parsing, meaning you can test your parser in isolation, and added type information to document your design.
添加
return val
或简单地编写return $ case ...
。do ...
中的最后一个语句必须是表达式。在您的特定情况下,它必须是IO Bool
类型的表达式,因此您需要使用return
函数将值提升到 IO monad 中。您还需要显式指定v
的类型(为此,您可能需要ScopedTypeVariables
GHC 扩展。)编写一个单独的类型 < 的纯函数也是一个好主意 。代码>字符串-> Bool 并在不纯的 IO 代码中使用它。
Add
return val
or simply writereturn $ case ...
. The last statement indo ...
must be an expression. In your particular case it must be an expression of typeIO Bool
, so you need to lift value into IO monad withreturn
function. You also need to specify type forv
explicitly (you will probably needScopedTypeVariables
GHC extension for this.)It is also a good idea to write a separate pure function of type
String -> Bool
and use it in the impure IO code.