Haskell IO函数适用于各种数据类型

时间:2012-12-08 08:29:05

标签: haskell io

我对几乎一无所知,我正在阅读大量的教程和代码示例,以了解 Haskell 的IO,但我仍然不清楚。

所有例子都是:

main = do  
    putStrLn "Hello, what's your name?"  
    name <- getLine  
    putStrLn ("Hey " ++ name ++ ", welcome !") 

他们从IO读取一个字符串,还有很多其他的例子可以对我不理解的输入进行一些自定义。

我的问题很简单:如何阅读IntFloatDoubleChar,例如在 C 中使用scanf用格式字符串?

任何人都可以帮我解释IO定制或技巧吗?

  

提示:如果代码附带了一个主函数   太棒了 - 它会让测试变得更容易。

我在CC++JavaC#MatlabPHP方面拥有非常好的编码经验。

3 个答案:

答案 0 :(得分:4)

最直接的方法是使用read(您通常必须提供显式类型),如

main = do  
    putStrLn "Hello, what's your age?"  
    age <- liftM read getLine :: IO Int
    putStrLn ("Hey " ++ (show age)  ++ ", welcome !")

如果您知道字符串只包含单个值(如果它无法将字符串解析为所需的数据类型,则抛出异常),这很有效。对于更复杂的解析,我通常会直接跳转到Parsec解析器组合库(这可能是Haskell中您需要的所有解析器,但也可以以最小的开销处理简单的作业)。如果这不适合您,快速搜索Hackage会显示一些候选库提供更简单的类似scanf的功能:请参阅Text.XFormat.ReadText.PrintScan,尽管我不能亲自担保。

答案 1 :(得分:3)

isturdy的回答是有效的,但是如果你想要更简单的东西,最简单的方法是逐步完成:

main = do
    i' <- getLine -- some integral input; it will be received as a String
    d' <- getLine -- some floating input; also will be received as a String
    let i = read i' :: Int -- i is an Int now
        d = read d' :: Double -- d is a Double now
    putStr "" -- so that GHC doesn't complain

getLine的类型为IO String - 它将输入读作String。然后,您可以使用read更改此字符串的类型(并指明您想要的类型)。对于类似scanf的体验,你可以尝试这样的事情:

main = do
    inp <- getLine -- the input is an Int, a String and a Double, like: 4 derp 2.7
    let list = words inp -- divide the input String into a list of Strings
        val = read (list !! 0) :: Int -- val equals 4, its type is Int
        str = list !! 1 -- str is a String ("derp"), no additional action required
        dbl = read (list !! 2) :: Double -- dbl equals 2.7 and is a Double
    putStr ""

答案 2 :(得分:1)

你应该深入阅读类型类。它是可以从字符串读取的值的标准类型,在不需要错误报告时在受控环境中非常有用。如果您希望读取自己的数据类型,则可能必须使用deriving Read语句。

但是,如果想要读取任意输入,则使用parsec库是标准的。 Parsec是具有多个预定义基本解析器的解析器组合器库。 extra package为数字提供了许多解析器。还存在特殊的高速解析器组合库和解析器生成器。