Proposal: Make digitToInt and intToDigit work up to base 36

Hello List, I propose to change the functions digitToInt and intToDigit in Data.Char to digitToInt :: Char -> Int digitToInt c | isDigit c = ord c - ord '0' | c >= 'a' && c <= 'z' = ord c - ord 'a' + 10 | c >= 'A' && c <= 'Z' = ord c - ord 'A' + 10 | otherwise = error ("Char.digitToInt: not a digit " ++ show c) intToDigit :: Int -> Char intToDigit i | i >= 0 && i <= 9 = toEnum (fromEnum '0' + i) | i >= 10 && i <= 35 = toEnum (fromEnum 'a' + i - 10) | otherwise = error "Char.intToDigit: not a digit" (and equivalently for the Ghc specialized version in Data.Show) Right now the functions only work for c <= 'f' and i <= 15, i.e. only up to hexadecimal. But I can think of no reason why that should be the case. There is the problem of compatibility with the Haskell98/2010 report. But since this proposed change only reduces the number of cases that are errors, I think that is not a big concern. Discussion period: 2 weeks, deadline July 13. Twan

Hi Twan, On Fri, Jun 29, 2012 at 10:59:11PM +0200, Twan van Laarhoven wrote:
Right now the functions only work for c <= 'f' and i <= 15, i.e. only up to hexadecimal. But I can think of no reason why that should be the case.
Have you got a real world use case for this? Thanks Ian

On 29/06/12 23:12, Ian Lynagh wrote:
Hi Twan,
On Fri, Jun 29, 2012 at 10:59:11PM +0200, Twan van Laarhoven wrote:
Right now the functions only work for c <= 'f' and i <= 15, i.e. only up to hexadecimal. But I can think of no reason why that should be the case.
Have you got a real world use case for this?
Not really. It just came up on #haskell, and the arbitrary limit has bothered me before every time I've seen it. On 02/07/12 19:17, Bryan O'Sullivan wrote:
This seems like a very strange change to want to make.
It already surprised me that digitToInt accepted hex digits; having it accept digits in number bases that nobody uses seems like even less desirable behaviour.
Changing the function to only work for decimal digits would be another way to get rid of the wart, but that might break existing code, unfortunately. Since people seem to be against the proposal, I'll hereby withdraw it. Twan

Hi List, Twan,
I would argue the opposite: the function name indicates that it will
transform a *digit* into an *int*. Digits in most cases any developer will
deal with are `elem` [0 .. 9], so it would make more sense to produce an
error for anything else, and provide a *separate *function, hexDigitToInt with
the hex reading behavior. (This would be a silently breaking change, so I'd
think carefully before seriously proposing this.) Twan is suggesting what
amounts to englishAlphaOrDigitToInt; is there any particular reason to give
the English alphabet special treatment in this case? I could instead
imagine the usefulness of alphaPos :: Alphabet -> Char -> Int which
indicates what position a given character is in its alphabet (alphaPos
English 'a' == 1, for instance), and its inverse alphaFromPos :: Alphabet
-> Int -> Char.
But if I am trying to read a number from a String, I would almost certainly
want it to fail on encountering any non-hex digit, rather than producing a
strange number.
--
Dan Burton
On Fri, Jun 29, 2012 at 2:59 PM, Twan van Laarhoven
Hello List,
I propose to change the functions digitToInt and intToDigit in Data.Char to
digitToInt :: Char -> Int digitToInt c | isDigit c = ord c - ord '0' | c >= 'a' && c <= 'z' = ord c - ord 'a' + 10 | c >= 'A' && c <= 'Z' = ord c - ord 'A' + 10 | otherwise = error ("Char.digitToInt: not a digit " ++ show c)
intToDigit :: Int -> Char intToDigit i | i >= 0 && i <= 9 = toEnum (fromEnum '0' + i) | i >= 10 && i <= 35 = toEnum (fromEnum 'a' + i - 10) | otherwise = error "Char.intToDigit: not a digit"
(and equivalently for the Ghc specialized version in Data.Show)
Right now the functions only work for c <= 'f' and i <= 15, i.e. only up to hexadecimal. But I can think of no reason why that should be the case.
There is the problem of compatibility with the Haskell98/2010 report. But since this proposed change only reduces the number of cases that are errors, I think that is not a big concern.
Discussion period: 2 weeks, deadline July 13.
Twan
______________________________**_________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/**mailman/listinfo/librarieshttp://www.haskell.org/mailman/listinfo/libraries

On 30 June 2012 07:44, Dan Burton
I could instead imagine the usefulness of alphaPos :: Alphabet -> Char -> Int which indicates what position a given character is in its alphabet (alphaPos English 'a' == 1, for instance), and its inverse alphaFromPos :: Alphabet -> Int -> Char.
I find myself doing something along these lines (but usually with 'a' -> 0) often enough that I would support adding such functions.
But if I am trying to read a number from a String, I would almost certainly want it to fail on encountering any non-hex digit, rather than producing a strange number.
Agreed. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com http://IvanMiljenovic.wordpress.com

On Fri, Jun 29, 2012 at 1:59 PM, Twan van Laarhoven
I propose to change the functions digitToInt and intToDigit in Data.Char [...]
This seems like a very strange change to want to make. It already surprised me that digitToInt accepted hex digits; having it accept digits in number bases that nobody uses seems like even less desirable behaviour. Quite strongly against this.

-1 as well
On Mon, Jul 2, 2012 at 1:17 PM, Bryan O'Sullivan
On Fri, Jun 29, 2012 at 1:59 PM, Twan van Laarhoven
wrote: I propose to change the functions digitToInt and intToDigit in Data.Char [...]
This seems like a very strange change to want to make.
It already surprised me that digitToInt accepted hex digits; having it accept digits in number bases that nobody uses seems like even less desirable behaviour.
Quite strongly against this.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Am 02.07.2012 19:17, schrieb Bryan O'Sullivan:
It already surprised me that digitToInt accepted hex digits;
This indicates that digitToInt is broken anyway (or should be named hexDigitToInt). For the decimal case you would need to use "isDigit" anyway and then could use just "ord c - ord '0'" instead of "digitToInt". So a (more) total implementation of intToDigit could avoid some tests leaving it to the programmer to decide between speed and safety. Cheers Christian | c <= '9' = ord c - ord '0' | c >= 'a' = ord c - ord 'a' + 10 | otherwise = ord c - ord 'A' + 10
participants (7)
-
Bryan O'Sullivan
-
Christian Maeder
-
Dan Burton
-
Edward Kmett
-
Ian Lynagh
-
Ivan Lazar Miljenovic
-
Twan van Laarhoven