[Haskell-cafe] Newbie question about Read strings in a line of
cgibbard at gmail.com
Tue Jul 26 14:39:48 EDT 2005
Here's how I wrote it:
----- beginning of file
-- turn a line of the text file into a pair consisting of
-- the message triple and the message string
-- slight bug: will contract multiple spaces in the message string
-- This could be rewritten to avoid this problem, but couldn't make as
much use of
-- existing prelude functions to do the work.
readMessage :: String -> ((Integer, Integer, Integer), String)
readMessage line = let (lang:typ:idx:msgWds) = words line
msg = unwords msgWds
in ((read lang, read typ, read idx),msg)
-- An IO action which gets a list of such pairs given a filename.
readMessagesFile filename = do hdl <- openFile filename ReadMode
cs <- hGetContents hdl
return $ map readMessage (lines cs)
-- An IO action which gets a lookup function for the message codes
given a filename.
getMessageLookup :: String -> IO ((Integer, Integer, Integer) -> Maybe String)
getMessageLookup filename = do msgs <- readMessagesFile filename
return (flip lookup msgs)
----- end of file
You can then test this in GHCi with something like
msgLookup <- getMessageLookup "messages.txt"
which should result in:
Just "Error message 1"
The values are wrapped in the "Just" constructor, and typed in the
Maybe monad, since the lookup might fail, in which case the msgLookup
will return the value "Nothing". Also note that this is somewhat
inefficient for very large numbers of messages, (lookup will be linear
in the number of messages in the worst case.) To get better
performance, a Map (see Data.Map) could be constructed, and the
lookups done on that, resulting in logarithmic time performance. The
interface would remain the same.
Hope this helps,
On 26/07/05, Huong Nguyen <hiperfume at gmail.com> wrote:
> Hello everybody,
> Now I am writing a module to handles messages of a system. The
> messages are stored in a file. The content of each line of the file
> likes this:
> 1 001 001 Error message 1
> 1 001 002 Error message 2
> 1 002 001 Warning message 1
> in which: The first word is the language Code (e.g: 1 is English, 2 is
> French), the second is type of messages (e.g: 001 is error message,
> 002 is warning message,etc), the third is the index number of
> messages, and the last is the message. I need to read 3 first words of
> each line and assign them to 3 variables. After that, I need to show
> the error message based on the tuple of those 3 first variable, e.g:
> errMsg("1","001","001") = "Error message 1"
> At first, I tried to read only one first line of the file as follows:
> import Prelude
> import List
> import Char
> import IO
> main = do hdl <- openFile "message.txt" ReadMode
> msgLine <-hGetLine hdl
> --stdMsg: cut space at the begining of the line.
> let stdMsg = dropWhile(not.isSpace) msgLine
> -Assign langCode with the first word of the line.
> let langCode = takeWhile(not.isSpace) stdMsg
> However, after that, I do not know how to read second element, third
> element of the line. And how to read continuous next line after first?
> Please help me. Thanks a lot.
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
More information about the Haskell-Cafe