将array-string读入变量

时间:2013-05-29 11:23:17

标签: haskell

我的文本文件包含如下数据:

13.    
13.      
[(1,2),(2,3),(4,5)].

我想在Haskell中将其读入3个变量。但标准函数将其读作字符串,但考虑到我最后删除了点,我自己是否有任何内置的解析器函数可以使“13”和[(Integer,Integer)]的整数列出[(1,2),(2,3),(4,5)]

3 个答案:

答案 0 :(得分:4)

是的,它被称为read

let i = read "13" :: Integer
let ts = read "[(1,2),(2,3),(4,5)]" :: [(Integer, Integer)]

答案 1 :(得分:2)

Haskell强大的类型要求您知道自己得到了什么。因此,让我们放弃所有错误检查和优化,并假设文件始终采用正确的格式,您可以这样做:

data Entry = Number Integer
           | List [(Integer, Integer)]

parseYourFile :: FilePath -> IO [Entry]
parseYourFile p = do
  content <- readFile p
  return $ parseYourFormat content

parseYourFormat :: String -> [Entry]
parseYourFormat data = map parseEntry $ lines data

parseEntry :: String -> Entry
parseEntry line = if head line == '['
                  then List $ read core
                  else Number $ read core
    where core = init line

或者您可以使用众多组合框架之一为其编写适当的解析器。

答案 2 :(得分:2)

您提供的示例文本文件具有尾随空格和句号,因此仅剪切最后一个字符不起作用。我们只使用数字:

import Data.Char (isDigit)

为什么没有数据类型来存储文件中的内容:

data MyStuff = MyStuff {firstNum :: Int,
                        secondNum:: Int,
                        intPairList :: [(Integer, Integer)]}
    deriving (Show,Read)

现在我们需要读取文件,然后将其转换为单独的行:

getMyStuff :: FilePath -> IO MyStuff
getMyStuff filename = do
   rawdata <- readFile filename
   let [i1,i2,list] = lines rawdata
   return $ MyStuff  (read $ takeWhile isDigit i1)  (read $ takeWhile isDigit i2)  (read $ init list)

read函数适用于任何具有Read实例的数据类型,并自动生成正确类型的数据。

> getMyStuff "data.txt" >>= print
MyStuff {firstNum = 13, secondNum = 13, intPairList = [(1,2),(2,3),(4,5)]}

更好的方法

我倾向于为自己省下一些工作,直接写出这些数据,所以

writeMyStuff :: FilePath -> MyStuff -> IO ()
writeMyStuff filename somedata = writeFile filename (show somedata)

readMyStuff :: FilePath -> IO MyStuff
readMyStuff filename = fmap read (readFile filename)

fmap只将纯函数read应用于readFile的输出。)

> writeMyStuff "test.txt" MyStuff {firstNum=12,secondNum=42, intPairList=[(1,2),(3,4)]}
> readMyStuff "test.txt" >>= print
MyStuff {firstNum = 12, secondNum = 42, intPairList = [(1,2),(3,4)]}

如果你让编译器为你排序,代码更少,更简单,你就不太可能做出很少的解析或打印错误。