Twan van Laarhoven | 29 Jun 22:59 2012
Picon

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
(Continue reading)

Ian Lynagh | 29 Jun 23:12 2012
Picon

Re: Proposal: Make digitToInt and intToDigit work up to base 36


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
Twan van Laarhoven | 5 Jul 17:45 2012
Picon

Re: Proposal: Make digitToInt and intToDigit work up to base 36

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
Dan Burton | 29 Jun 23:44 2012
Picon

Re: Proposal: Make digitToInt and intToDigit work up to base 36

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 <twanvl <at> gmail.com> wrote:
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 <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Ivan Lazar Miljenovic | 30 Jun 00:26 2012
Picon

Re: Proposal: Make digitToInt and intToDigit work up to base 36

On 30 June 2012 07:44, Dan Burton <danburton.email <at> gmail.com> wrote:
> 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 <at> gmail.com
http://IvanMiljenovic.wordpress.com

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Bryan O'Sullivan | 2 Jul 19:17 2012

Re: Proposal: Make digitToInt and intToDigit work up to base 36

On Fri, Jun 29, 2012 at 1:59 PM, Twan van Laarhoven <twanvl <at> gmail.com> 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 <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Edward Kmett | 2 Jul 20:40 2012
Picon

Re: Proposal: Make digitToInt and intToDigit work up to base 36

-1 as well

On Mon, Jul 2, 2012 at 1:17 PM, Bryan O'Sullivan <bos <at> serpentine.com> wrote:
On Fri, Jun 29, 2012 at 1:59 PM, Twan van Laarhoven <twanvl <at> gmail.com> 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 <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Christian Maeder | 3 Jul 11:21 2012
Picon

Re: Proposal: Make digitToInt and intToDigit work up to base 36

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

Gmane