[Haskell-beginners] Re: define action getInt like getLine

Christian Maeder Christian.Maeder at dfki.de
Tue Feb 9 06:49:49 EST 2010


kane96 at 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,  <kane96 at gmx.de> 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.



More information about the Beginners mailing list