我认为您最好自己弄清楚其中的大部分内容,但我有一些建议给您。
首先,在其余代码正常工作之前,尽量不要处理文件访问,否则您最终可能会到处都有 IO。从一些示例数据开始:
sampleData = "[m1,m2,m3][x1,x2,x3,x4]\n[f3,f4,f5][y7,y8,y123]\n[m4,m5,m6][x5,x6,x7,x8]"
您不应该在代码中的任何其他地方提及sampleData,但您应该在 ghci 中使用它进行测试。
一旦你有一个可以做任何你想做的事情的函数,例如processLists::String->[(String,String)],你可以用
复制
readFile "data.txt" :: IO String
readInLists :: FilePath -> IO [(String,String)]
readInLists filename = fmap processLists (readFile filename)
如果fmap 对您没有意义,您可以阅读tutorial I accidentally wrote。
如果它们真的是字母数字,您可以很容易地拆分它们。以下是一些方便的函数,并附有示例。
tail :: [a] -> [a]
tail "(This)" = "This)"
你可以用它在你的字符串前面扔掉你不想要的东西。
break :: (Char->Bool) -> String -> (String,String)
break (== ' ') "Hello Mum" = ("Hello"," Mum")
所以break 使用测试来查找第二个字符串的第一个字符,并打破它之前的字符串。
请注意,中断字符仍然存在于下一个字符串的前面。 span 是相同的,但使用测试来测试第一个列表中的内容,所以
span :: (Char->Bool) -> String -> (String,String)
span (/= ' ') "Hello Mum" = ("Hello"," Mum")
您可以将这些函数与(==',') 或isAlphaNum 等内容一起使用(您必须在文件顶部添加import Data.Char 才能使用它)。
您可能想查看this answer 中的函数splitWith 和splitOn。它们基于 Prelude 中split 和words 的定义。