Haskell 将数组字符串读入变量
我有一个包含如下数据的文本文件:Haskell 将数组字符串读入变量,haskell,Haskell,我有一个包含如下数据的文本文件: 13. 13. [(1,2),(2,3),(4,5)]. 我想把它读入Haskell的3个变量中。但是标准函数将其读取为字符串,但是考虑到我自己在最后去掉了点,是否有任何内置的解析器函数可以将整数“13”和[(整数,整数)]从[(1,2),(2,3),(4,5)]中列出?是的,它被称为read: let i = read "13" :: Integer let ts = read "[(1,2),(2,3),(4,5)]" :: [(Int
13.
13.
[(1,2),(2,3),(4,5)].
我想把它读入Haskell的3个变量中。但是标准函数将其读取为字符串,但是考虑到我自己在最后去掉了点,是否有任何内置的解析器函数可以将整数“13”和
[(整数,整数)]
从[(1,2),(2,3),(4,5)]
中列出?是的,它被称为read
:
let i = read "13" :: Integer
let ts = read "[(1,2),(2,3),(4,5)]" :: [(Integer, Integer)]
是的,它被称为
read
:
let i = read "13" :: Integer
let ts = read "[(1,2),(2,3),(4,5)]" :: [(Integer, Integer)]
哈斯凯尔的强势类型要求你知道自己得到了什么。因此,让我们放弃所有错误检查和优化,并假设文件始终采用正确的格式,您可以这样做:
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
数据输入=数字整数
|列表[(整数,整数)]
parseYourFile::FilePath->IO[输入]
parseyourfilep=do
内容[条目]
parseYourFormat数据=映射parseEntry$行数据
parseEntry::String->Entry
parseEntry line=如果头行=='['
然后列出$readcore
else编号$read core
其中core=init行
或者,您可以使用众多combinator框架中的一种为其编写适当的解析器。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
数据输入=数字整数
|列表[(整数,整数)]
parseYourFile::FilePath->IO[输入]
parseyourfilep=do
内容[条目]
parseYourFormat数据=映射parseEntry$行数据
parseEntry::String->Entry
parseEntry line=如果头行=='['
然后列出$readcore
else编号$read core
其中core=init行
或者,您可以使用多种combinator框架中的一种为其编写一个合适的解析器。您给出的示例文本文件有尾随空格和句号,因此仅剪切最后一个字符不起作用。让我们使用以下方法仅取数字:
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)
更好的方法
我倾向于为自己节省一些工作,直接写数据,所以
writeMyStuff :: FilePath -> MyStuff -> IO ()
writeMyStuff filename somedata = writeFile filename (show somedata)
readMyStuff :: FilePath -> IO MyStuff
readMyStuff filename = fmap read (readFile filename)
(fmap
仅将纯函数read
应用于readFile
的输出)
如果让编译器为您整理所有内容,您的解析或打印错误可能会小得多,代码更少,也更简单。您给出的示例文本文件有尾随空格和句号,因此仅剪切最后一个字符不起作用。让我们使用以下方法仅获取数字:
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)
更好的方法
我倾向于为自己节省一些工作,直接写数据,所以
writeMyStuff :: FilePath -> MyStuff -> IO ()
writeMyStuff filename somedata = writeFile filename (show somedata)
readMyStuff :: FilePath -> IO MyStuff
readMyStuff filename = fmap read (readFile filename)
(fmap
仅将纯函数read
应用于readFile
的输出)
如果让编译器为您整理所有内容,那么您就不太可能出现小的解析或打印错误,代码更少,也更简单。Prelude.read无解析错误。我有这样的代码:data EntryData=EntryData{height::Integer,width::Integer,entryList:[(Integer,Integer)]派生(显示、读取)getEntryData::FilePath->IO EntryData getEntryData文件名=do rawdata=打印字符串是否正确:(@user2349668我正在打电话,但是你确定文件中包含数据,然后是句点,然后是行的结尾吗?如果没有,map init将不会删除跟踪空格。用print而不是putStrLn测试它,以找出文件中还有哪些空白。Prelude.read无解析错误。我有这样的代码:data EntryData=EntryData{height::Integer,width::Integer,entryList::[(Integer,Integer)]}派生(显示,读取)getEntryData::FilePath->IO EntryData getEntryData filename=do rawdata=打印字符串正确:(@user2349668我现在在手机上,但是你确定文件中包含数据,然后是句点,然后是行的结尾吗?如果没有,map init将不会删除跟踪空格。请使用print而不是putStrLn对其进行测试,以找出文件中还有哪些空白。