
kane96@gmx.de schrieb:
but I have to write the action readMonth :: IO Month on my own and still don't have an idea how to do it
Your idea (below) to use show on all possible values and compare it to the input line isn't that bad.
On 8 February 2010 21:19,
wrote: I want to read a "Month" from input and if this month issn't declared in my data type "Month" I want to throw an error message. data Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Ago | Sep | Oct | Nov | Dec deriving (Eq,Enum,Show)
The Enum class allows you to create the list of all possible values [Jan .. Dec] This list can be turn into a lookup-list (for Data.List.lookup) by map (\ a -> (show a, a))
readMyDatatype = do if readLn == (show readLn) then return readLn else do error "input error"
This code is unfortunate, because "readLn" is an IO-Action (that cannot be compared or shown). Even if you insert as first line: readLn <- getLine readLn is a String that will never be equal to "show readLn", because show would add the double quotes. Also this shadowing of "readLn" is no good practise and should be avoided, so better use: str <- getLine and use the string "str" to look it up in the list above. Later on you may generalize readMonth to: readMyDatatype :: (Show a, Enum a, Bounded a) => IO a and also trim leading and trailing white space and case differences. Cheers Christian P.S. The functions read, readIO and readLn all have disadvantages in case of errors. In the spirit of readIO it is possible to program readMaybe, readEither or readM that are far more useful and missed very often. Many such variants are somewhere, but one of readMaybe, readEither or readM should be in a standard library. readM would not be a generalization of readIO! But readIO could be expressed using readM.