
Today's other question has to do with numeric literals. How do I write literals for interesting IEEE values, e.g.
Prelude> x Infinity Prelude> :type x Double Prelude> (read "Infinity") :: Double *** Exception: Ratio.%: zero denominator Prelude>
This looks like a bug in GHC, which has now been fixed for version 5.02. Note that Haskell leaves the behaviour of these exceptional conditions undefined. Hugs for example will give a program error on divide by zero, and NHC has even more interesting behaviour: Prelude> 1/0 :: Float 34.02823669209384634633746074317682114560000000 Cheers, Simon

On Tue, 28 Aug 2001, Simon Marlow wrote: (snip)
Note that Haskell leaves the behaviour of these exceptional conditions undefined. Hugs for example will give a program error on divide by zero, and NHC has even more interesting behaviour:
Prelude> 1/0 :: Float 34.02823669209384634633746074317682114560000000
!! Damn - that's annoying. I've come to take the existence of reasonable IEEE 754 floating point support for granted - is it really generally that bad in Haskell? Are there any libraries and whatnot that will help fix this? I like at least for plus and minus infinities and NaNs to be part of things. (-: My first thought was to learn about the FFI and do actual arithmetic and the relevant reading and showing in another language that I link with, but I fear the speed penalty, and now I think about it I might be able to reasonably transparently deal with the cases I care about in pure Haskell. I also haven't yet worked out how to tell if a string is "read"able or not, yet - if (read "45")::Integer or whatever gives an error (e.g. if I'd put "af" instead of "45"), it seems to be pretty uncatchable, which is a pain. How do I tell if an instance of reading will work, or catch that it didn't? I know things must be better than this - I must be missing something? (-: Thanks. -- Mark

On Tue, 28 Aug 2001, Mark Carroll wrote:
How do I tell if an instance of reading will work, or catch that it didn't?
Short: check the resulting list from reads "some string" In the Read class we have also reads :: Read a => ReadS a type ReadS a = String -> [(a,String)] [A ghci test session follows] Prelude> reads "123.45a" :: [(Float,String)] [(123.45,"a")] Prelude> reads "123a.45" :: [(Float,String)] [(123.0,"a.45")] Prelude> reads "a123.45" :: [(Float,String)] [] Prelude> reads "Infinity" :: [(Float,String)] *** Exception: Ratio.%: zero denominator /Patrik

Mark Carroll wrote:
I also haven't yet worked out how to tell if a string is "read"able or not, yet - if (read "45")::Integer or whatever gives an error (e.g. if I'd put "af" instead of "45"), it seems to be pretty uncatchable, which is a pain. How do I tell if an instance of reading will work, or catch that it didn't?
You need to resort to reads :: Read a => ReadS a where ReadS is a typical parser type constructor (``replacing failure by a list of successes'', see BibTeX entry below), defined in the prelude: type ReadS a = String -> [(a,String)] You might want to wrap it in something like the following: read' :: Read a => String -> Maybe a read' s = case reads s of ((a,[]):_) -> Just a _ -> Nothing For understanding the machinery it is useful to look at the class and instance definitions for Read in the Prelude. Wolfram ========================================================= @InProceedings{Wadler-1985a, author = "Philip Wadler", title = "How to Replace Failure by a List of Successes --- {A} Method for Exception Handling, Backtracking, and Pattern Matching in Lazy Functional Languages", booktitle = {Proceedings of the Second Conference on Functional Programming Languages and Computer Architecture}, confaddress = "Nancy, France", publisher = Springer, series = LNCS, confdate = SEP # " 16--19,", year = "1985", pages = "113--128", }

On Tue, 28 Aug 2001, Patrik Jansson wrote: (snip)
Prelude> reads "123.45a" :: [(Float,String)] [(123.45,"a")] Prelude> reads "123a.45" :: [(Float,String)] [(123.0,"a.45")] Prelude> reads "a123.45" :: [(Float,String)] [] Prelude> reads "Infinity" :: [(Float,String)] *** Exception: Ratio.%: zero denominator
On 28 Aug 2001 kahl@heraklit.informatik.unibw-muenchen.de wrote:
You might want to wrap it in something like the following:
read' :: Read a => String -> Maybe a read' s = case reads s of ((a,[]):_) -> Just a _ -> Nothing
Thanks very much for this, too. That is also most useful. This is a great list - I'll try not to abuse everyone's willingness to help! (-: I'm still trying to understand Chris Angus' suggestion, but it's just a matter of me spending enough time on it. I assume the Infinity problem above is just a bug that isn't fixed in that GHC. -- Mark
participants (4)
-
kahl@heraklit.informatik.unibw-muenchen.de
-
Mark Carroll
-
Patrik Jansson
-
Simon Marlow