The most literal way to write getInt would be:
getInt :: IO Int
getInt = do
s <- getLine
return (read s)
which is just a more verbose version of:
getInt' = read `fmap` getLine
The above versions don't do any error checking, so you might
prefer a getInt :: IO Maybe Int which returns Nothing in case the input
is not an integer.
You should read up on Monadic IO in Haskell. The Real World Haskell book
is probably a good starting point.
Rahul
There are many possibilities.
The shortest is
getInt :: IO Int
getInt = readLn
another short and sweet is
getInt :: IO Int
getInt = fmap read getLine -- or liftM read getLine
But neither of these deals well with malformed input, if that's a
possibility to reckon with, use e.g. the reads function
getInt :: IO Int
getInt = do
inp <- getLine
case reads inp of
((a,tl):_) | all isSpace tl -> return a
_ -> handle malformed input
here's another idea :
saisie_choix :: IO Int
saisie_choix=do
putStrLn "Type in 1 digit :"
xchoix <- getLine
if (length xchoix) /= 1 || head xchoix < '0' || head xchoix > '9'
then saisie_choix
else do
let nchoix=read xchoix::Int
return nchoix
or, with maybe :
{- -------------- MAYBE ------------------ -}
-- Fonction principale
mainmaybe=do
x <- lire
if isNothing x
then do
putStrLn "Donnee invalide"
else do
putStr " \b"
putStrLn ("Resultat : " ++ show (f x))
-- D�finition de la fonction de calcul
f Nothing = -9999
f (Just x) = 2 * x
-- Fonction d'IO qui valide la saisie
lire :: IO (Maybe Integer)
lire = do
-- saisie
xn <- getLine
let x=read xn ::Integer
-- validation
if x < 5
then do
return (Just x)
else do
return Nothing
Didier.
Rahul Kapoor a �crit :
That's already in the standard libs:
ghci> :t maybe
maybe :: b -> (a -> b) -> Maybe a -> b
ghci> maybe (-9999) (*2) (Just $ fromEnum 'k')
214
I have to do it for a more complex case of reading an own data type (myDatatype) with is deriving Show and return an error otherwise.
I tried the following which didn't work:
readMyDatatype :: IO myDatatype
readMyDatatype = do
if readLn == (show readLn)
then return readLn
else do error "input error"
-------- Original-Nachricht --------
> Datum: Tue, 2 Feb 2010 22:39:07 +0100
> Von: Daniel Fischer <daniel.i...@web.de>
> An: begi...@haskell.org
> CC: kan...@gmx.de
> Betreff: Re: [Haskell-beginners] define action getInt like getLine
--
NEU: Mit GMX DSL �ber 1000,- � sparen!
http://portal.gmx.net/de/go/dsl02
Data types are required to start with a capital letter, so you'll have
to call it MyDatatype. I can't see where readLn is defined. Can you
paste a bit more of the code? I don't quite understand how your reading
of your own data type is meant to work - normally you would use read or
reads from the Read type class.
A more subtle point - because of the way lazy evaluation works, it is
generally better to use 'fail' rather than 'error' when in a monad. In
some monads it's possible that 'error' may do nothing.
Steve
data Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Ago | Sep | Oct | Nov | Dec deriving (Eq,Enum,Show)
-------- Original-Nachricht --------
> Datum: Mon, 08 Feb 2010 09:25:13 +1300
> Von: "Stephen Blackheath [to Haskell-Beginners]" <mutilating.caul...@blacksapphire.com>
> An: kan...@gmx.de
> CC: begi...@haskell.org
--
GRATIS f�r alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
-------- Original-Nachricht --------
> Datum: Mon, 8 Feb 2010 21:27:42 +0000
> Von: Stephen Tetley <stephen...@gmail.com>
> An:
> CC: begi...@haskell.org
> Betreff: Re: [Haskell-beginners] define action getInt like getLine
> Hello
>
> You can derive Read:
>
> > data Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Ago | Sep | Oct |
> Nov | Dec deriving (Eq,Enum,Show,Read)
>
> This will certainly throw an error on failure (might not be an error
> you would want to transmit to a user though), and it will only read
> "Jan" not "jan" or "January"...
>
> Plenty of good suggestions in this thread:
>
> http://www.haskell.org/pipermail/haskell-cafe/2010-January/072177.html
>
>
> Best wishes
>
> Stephen
Go take a look at
http://www.haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html#v%3Aread
http://www.haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html#v%3AreadLn
http://www.haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html#v%3AgetLine
The documentation should help you.
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, <kan...@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.
-------- Original-Nachricht --------
> Datum: Mon, 8 Feb 2010 22:26:59 +0000
> Von: Stephen Tetley <stephen...@gmail.com>
> An: kan...@gmx.de
> Betreff: Re: [Haskell-beginners] define action getInt like getLine
> Hello
>
> Upthread Daniel Fisher posted this one
>
> getInt :: IO Int
> getInt = fmap read getLine
>
> If you check the type of read
>
> *GHCi> :t read
> read :: (Read a) => String -> a
>
> 'reads' is polymorphic it will read anything from a String - well
> within reason, anything that is an instance of the Read type class.
> The "(Read a) => " part of the type signature indicates this
> constraint - that "a" ( the return type of the function read) must be
> an instance of Read.
>
> As I wrote, you can easily derive an instance of Read by adding Read
> to the deriving clause of your data type, so the next thing to do is
> write a function swapping as few parts from Daniel's example as
> possible:
>
> -- Here you have to make a change as you want a Month rather than an
> Int, so swap the ??? for what you want...
> getMonth :: IO ???
>
> -- The function definition can stay the same - none of the components
> in Daniel's definition actually depended on reading an Int:
> getMonth = fmap read getLine
>
>
>
> On 8 February 2010 21:43, <kan...@gmx.de> wrote:
> > but I have to write the action
> > readMonth :: IO Month
> > on my own and still don't have an idea how to do it
> >
> >
--