
Is there a reason to not allow '.' as a separator for Rational's Read instance, so that both "1%2" and "0.5" can be read? Tom

Hi Tom, On Sun, Aug 14, 2016 at 9:48 PM, Tom wrote:
Is there a reason to not allow '.' as a separator for Rational's Read instance, so that both "1%2" and "0.5" can be read?
While it would make read :: String -> Rational more convenient, I'm not sure it would be a good idea to have read accept input that will never be produced by show :: Rational -> String. As an alternative, you can use readFloat [1] in Numeric. Regards, Sean [1] https://hackage.haskell.org/package/base-4.9.0.0/docs/Numeric.html#v:readFlo...

On 14 August 2016 at 16:00, Sean Leather
On Sun, Aug 14, 2016 at 9:48 PM, Tom wrote:
Is there a reason to not allow '.' as a separator for Rational's Read instance, so that both "1%2" and "0.5" can be read?
While it would make read :: String -> Rational more convenient, I'm not sure it would be a good idea to have read accept input that will never be produced by show :: Rational -> String.
This already happens everywhere, right? For example, if you have a Foo { bar :: Int, baz :: String } with the derived read instance, this works: read "Foo{bar=0x01, baz = \"h\101llo\"}" :: Foo Erik

Hi Erik, On Sun, Aug 14, 2016 at 11:01 PM, Erik Hesselink wrote:
On 14 August 2016 at 16:00, Sean Leather wrote:
On Sun, Aug 14, 2016 at 9:48 PM, Tom wrote:
Is there a reason to not allow '.' as a separator for Rational's Read instance, so that both "1%2" and "0.5" can be read?
While it would make read :: String -> Rational more convenient, I'm not sure it would be a good idea to have read accept input that will never be produced by show :: Rational -> String.
This already happens everywhere, right? For example, if you have a Foo { bar :: Int, baz :: String } with the derived read instance, this works:
read "Foo{bar=0x01, baz = \"h\101llo\"}" :: Foo
True. I'm not sure how far down the decimal/scientific notation parsing hole you'd want to take the Ratio Read instance. Anyway, my point was that there is an existing alternative that doesn't require changing the instance and is not that inconvenient. Regards, Sean

Since decimal notation is defined in terms of fromRational, it seems a bit
strange that the notation doesn't work for read::String->Rational. I'd be
in favor of allowing it. I wouldn't expect too severe a performance penalty.
On Aug 14, 2016 5:28 PM, "Sean Leather"
Hi Erik,
On Sun, Aug 14, 2016 at 11:01 PM, Erik Hesselink wrote:
On 14 August 2016 at 16:00, Sean Leather wrote:
On Sun, Aug 14, 2016 at 9:48 PM, Tom wrote:
Is there a reason to not allow '.' as a separator for Rational's Read instance, so that both "1%2" and "0.5" can be read?
While it would make read :: String -> Rational more convenient, I'm not sure it would be a good idea to have read accept input that will never be produced by show :: Rational -> String.
This already happens everywhere, right? For example, if you have a Foo { bar :: Int, baz :: String } with the derived read instance, this works:
read "Foo{bar=0x01, baz = \"h\101llo\"}" :: Foo
True. I'm not sure how far down the decimal/scientific notation parsing hole you'd want to take the Ratio Read instance. Anyway, my point was that there is an existing alternative that doesn't require changing the instance and is not that inconvenient.
Regards, Sean
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On 08/14/2016 06:54 PM, David Feuer wrote:
Since decimal notation is defined in terms of fromRational, it seems a bit strange that the notation doesn't work for read::String->Rational. I'd be in favor of allowing it. I wouldn't expect too severe a performance penalty.
One potential gotcha: ghci> read (show (1/3)) == (1/3) True ghci> read (show (1/3 :: Float)) == (1/3) False When does it work? Is it platform-dependent?

Michael Orlitzky
On 08/14/2016 06:54 PM, David Feuer wrote:
Since decimal notation is defined in terms of fromRational, it seems a bit strange that the notation doesn't work for read::String->Rational. I'd be in favor of allowing it. I wouldn't expect too severe a performance penalty.
One potential gotcha:
ghci> read (show (1/3)) == (1/3) True ghci> read (show (1/3 :: Float)) == (1/3) False
When does it work? Is it platform-dependent?
Well, you are showing 1/3 as a Float and reading it as a Double, which of course won't work since the String represents a Float and not a Double. The following does work: λ: read (show (1/3 :: Float)) == ((1/3) :: Float) True

On 08/15/2016 09:04 AM, Benno Fünfstück wrote:
Well, you are showing 1/3 as a Float and reading it as a Double, which of course won't work since the String represents a Float and not a Double. The following does work:
Sorry, unclear example. We have a choice to make for how to read in decimal strings that could also represent Floats or Doubles. I'm worried about the resulting confusion from whatever choice we make. Read/Show are supposed to be machine-readable, and representing a Rational as a decimal (the same way a Float is represented) gives away some type-safety. This is the same argument I would make against having (read "1.0" :: Integer) return 1. Suppose that this is what the rational read instance would do... ghci> let ratread :: String -> Rational; ratread s = realToFrac (read s :: Double) :: Rational We're compatible with the Fractional/Show instance for Float/Double: ghci> fromRational $ ratread (show (0.33333334 :: Float)) :: Float 0.33333334 ghci> fromRational $ ratread (show (0.33333334 :: Double)) :: Double 0.33333334 But obviously things will go wrong for rationals themselves, when they don't fit into a Double. The other choice we could make is to take "0.33333334", multiply it by ten-to-the-whatever, and then make that the denominator (over ten-to-the-whatever). That's probably a better choice, but then you have other inconsistencies... ghci> 0.33333334 :: Rational 16666667 % 50000000 ghci> toRational (0.33333334 :: Float) 11184811 % 33554432 Namely, that that's not how the Float itself is converted into a Rational. Basically, beware of confusing the hell out of everyone in order to avoid an explicit type conversion.

That choice has already been made, with a different conclusion, in the
Haskell numeric syntax. In Haskell syntax, decimal syntax is interpreted
via fromRational *already*. In source, I can write 3.796::Rational and get
a good result, without any conversion from Double anywhere--it just puts
3796/1000 into lowest terms as it should. I see no particular reason to do
otherwise here. In either case, we need to read digits, building an
integer, until we get to a non-digit. Only what happens next depends on the
notation. Either notation should work for any Fractional type, as it does
in Haskell syntax.
On Aug 15, 2016 11:09 AM, "Michael Orlitzky"
On 08/15/2016 09:04 AM, Benno Fünfstück wrote:
Well, you are showing 1/3 as a Float and reading it as a Double, which of course won't work since the String represents a Float and not a Double. The following does work:
Sorry, unclear example. We have a choice to make for how to read in decimal strings that could also represent Floats or Doubles. I'm worried about the resulting confusion from whatever choice we make.
Read/Show are supposed to be machine-readable, and representing a Rational as a decimal (the same way a Float is represented) gives away some type-safety. This is the same argument I would make against having (read "1.0" :: Integer) return 1.
Suppose that this is what the rational read instance would do...
ghci> let ratread :: String -> Rational; ratread s = realToFrac (read s :: Double) :: Rational
We're compatible with the Fractional/Show instance for Float/Double:
ghci> fromRational $ ratread (show (0.33333334 :: Float)) :: Float 0.33333334 ghci> fromRational $ ratread (show (0.33333334 :: Double)) :: Double 0.33333334
But obviously things will go wrong for rationals themselves, when they don't fit into a Double. The other choice we could make is to take "0.33333334", multiply it by ten-to-the-whatever, and then make that the denominator (over ten-to-the-whatever). That's probably a better choice, but then you have other inconsistencies...
ghci> 0.33333334 :: Rational 16666667 % 50000000 ghci> toRational (0.33333334 :: Float) 11184811 % 33554432
Namely, that that's not how the Float itself is converted into a Rational. Basically, beware of confusing the hell out of everyone in order to avoid an explicit type conversion.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (6)
-
amindfv@gmail.com
-
Benno Fünfstück
-
David Feuer
-
Erik Hesselink
-
Michael Orlitzky
-
Sean Leather