Haskell:如何将 IO 输入字符串解析为 Float(或 Int 或其他)?

Posted

技术标签:

【中文标题】Haskell:如何将 IO 输入字符串解析为 Float(或 Int 或其他)?【英文标题】:Haskell: How to parse an IO input string into a Float (or Int or whatever)? 【发布时间】:2012-07-13 22:37:48 【问题描述】:

我正在尝试制作一个程序,该程序接受用户通过键盘输入的浮点数并对其进行处理。

但是,每次我尝试将输入的字符串解析为浮点数时,我都会不断出错。我尝试过的每一种方法都无法让我获取用户输入的数据并将其转换为我需要的浮点数。

我的练习计划(不是我要解决的实际问题)是:

main = do
    putStrLn "Please input a number."
    inputjar <- getLine
    read :: read a => String -> a
    putStrLn( read inputjar :: Int)

编辑

还有一个问题。

如何获取输入的字符串并将其转换为可用于计算的内容?

例如,我如何获取输入的字符串,以便我可以执行以下操作:

(var + var) / 2

【问题讨论】:

您能解释一下为什么您有read :: read a =&gt; String -&gt; a 表达式吗? (这是一个严肃的问题:explaining your own code in detail 是一种非常好的理解和调试方式。) 一个帮我的朋友告诉我把它放进去或读它是行不通的。那时我几乎尝试了任何事情,并认为这是必要的。 我认为这位朋友的意思是您可以使用其签名的特殊化来包装您对read 的使用,例如print ((read :: String -&gt; Int) inputjar)(我们在这里使用 print 因为它是数字,而不是我们正在使用的字符串。)编译器已经知道read 的最通用类型,即Read a =&gt; String -&gt; a,这无助于它找出什么用户的输入方式。在这种情况下,您也可以使用print (read inputjar ::Int)——您上面的主要错误是使用了putStrLn,它只作用于字符串,而不是打印。 @PhilipEloy:由于“有人在此页面上回答”,请接受相关答案。如果其他人问了基本相同的问题并且答案在该问题中,请在评论中链接到它,以便我们可以关闭这个作为另一个问题的重复链接。 【参考方案1】:
main = do
   putStrLn "Please input a number."
   inputjar <- readLn
   print (inputjar :: Int)

这在某种程度上更好,因为它立即将我们正在读取的字符串修复为:

main = do
   putStrLn "Please input a number."
   inputjar :: Int  <- readLn
   print inputjar

但它需要-#LANGUAGE ScopedTypeVariables#-

【讨论】:

inputjar &lt;- readLN :: IO Int,没有扩展。我的首选方法。 这里相同;在这种情况下,我拒绝使用IO 打字。 @applicative 这样对 IO 进行类型转换是不是很糟糕?似乎是最简单的解决方案,但听起来您有保留。【参考方案2】:

您在代码中说(read inputjar :: Int),但您告诉我们您想读取Float。你没有定义read,把那条线去掉。您使用putStrLn 以便打印出浮点数,但putStrLn 采用String,因此您需要show 的值。

main = do
    putStrLn "Please input a number."
    inputjar <- getLine
    putStrLn $ show (read inputjar :: Float)

【讨论】:

【参考方案3】:

putStrLn 打印出Strings,而不是Ints,所以有两种解决方案:

使用print,它打印任何实现Show的东西:

main = do
    putStrLn "Please input a number."
    inputjar <- getLine
    let n = read inputjar :: Int
    print n

.. 或在您阅读的原始String 上致电putStrLn

main = do
    putStrLn "Please input a number."
    inputjar <- getLine
    let n = read inputjar :: Int
    putStrLn inputjar

在后一个示例中,n 从未使用过,但您可能会在之后编写一些实际使用它的代码。

【讨论】:

【参考方案4】:

我猜是

read :: read a => String -> a

是不是弄错了?

反正在ghci下,:t putStrLn显示:

putStrLn :: String -> IO ()

所以putStrLn 只接受 String 作为它的第一个参数,所以如果你真的想要:

putStrLn( show (read inputjar :: Int))

顺便说一句,read inputjar :: int 是正确的,只是你的输出是错误的。

【讨论】:

好的,成功了。这太妙了。谢谢你。如果我想将 inputjar 的内容用于其他用途(例如实际计算),我还需要做什么?【参考方案5】:

这对我有用

import System.IO

getNum :: IO Integer 
getNum = readLn 

--call function like this
something <- getNum
--something is type Integer

【讨论】:

以上是关于Haskell:如何将 IO 输入字符串解析为 Float(或 Int 或其他)?的主要内容,如果未能解决你的问题,请参考以下文章

简单的输入函数Haskell

如何在 Haskell 中解析整数矩阵?

在 Haskell 中自动插入惰性

为什么会出现解析错误,如何在haskell中解决此错误?

使用 IO.readLn 从 Haskell 中的标准输入读取单行

Haskell:FRP 反应性 Parsec?