I have a text file which contains two lists on each line. Each list can contain any number of alphanumeric arguments. eg [t1,t2,...] [m1,m2,...] I can read the file into ghc, but how can I read this into another main file and how can the main file recognise each argument separately to then process it?
-
7What have you tried? Have you looked at the relevant sections of any Haskell tutorials or documentation? – Daniel Wagner Oct 30 '12 at 23:44
-
[This](http://www.learnyouahaskell.com/) is a great book to help you learn Haskell. It has a great chapter on I/O. – Code-Apprentice Oct 31 '12 at 01:32
1 Answers
I think it's best for you to figure out most of this for yourself, but I've got some pointers for you. Firstly, try not to deal with the file access until you've got the rest of the code working, otherwise you might end up having IO all over the place. Start with some sample data:
sampleData = "[m1,m2,m3][x1,x2,x3,x4]\n[f3,f4,f5][y7,y8,y123]\n[m4,m5,m6][x5,x6,x7,x8]"
You should not mention sampleData
anywhere else in your code, but you should use it in ghci for testing.
Once you have a function that does everything you want, eg processLists::String->[(String,String)]
, you can replcae readFile "data.txt" :: IO String
with
readInLists :: FilePath -> IO [(String,String)]
readInLists filename = fmap processLists (readFile filename)
If fmap
makes no sense to you, you could read a tutorial I accidentally wrote.
If they really are alphanumeric, you can split them quite easily. Here are some handy functions, with examples.
tail :: [a] -> [a]
tail "(This)" = "This)"
You can use that to throw away something you don't want at the front of your string.
break :: (Char->Bool) -> String -> (String,String)
break (== ' ') "Hello Mum" = ("Hello"," Mum")
So break
uses a test to find the first character of the second string, and breaks the string just before it.
Notice that the break character is still there at the front of the next string. span
is the same but uses a test for what to have in the first list, so
span :: (Char->Bool) -> String -> (String,String)
span (/= ' ') "Hello Mum" = ("Hello"," Mum")
You can use these functions with things like (==',')
, or isAlphaNum
(you'll have to import Data.Char
at the top of your file to use it).
You might want to look at the functions splitWith
and splitOn
that I have in this answer. They're based on the definitions of split
and words
from the Prelude.
-
2
-
2@Code-Guru I wrote an answer and it got rather out of hand. It ended up rather longer than my typical answers and now even has an appendix. It started as a quick few examples, but ended up as more of a tutorial. Oh well. – AndrewC Oct 31 '12 at 01:55
-
3The answer and tutorial keys are, like, right next to each other. – Gabriella Gonzalez Oct 31 '12 at 18:57
-