Proposal: Remove Num superclass of Bits

Bas van Dijk v.dijk.bas at
Sun Oct 16 02:33:58 CEST 2011

On 15 October 2011 21:16, Ian Lynagh <igloo at> wrote:
> On Sat, Oct 15, 2011 at 08:00:21PM +0200, Bas van Dijk wrote:
>> We can also combine Gábor's and Roman's solutions to get both
>> portability and convenience:
>>     zero, one :: a
>> #ifdef __GLASGOW_HASKELL__
>>     default zero, one :: Num a => a
>>     zero = 0
>>     one  = 1
>> #endif
> I think doing this conditionally is a bad idea. Programs will just fail
> at runtime when using other impls.
> I also think doing it unconditionally is a bad idea. It significantly
> raises the barrier to getting another impl to the point where it is
> useful.

Agreed, lets drop the default signatures idea.

> Hmm, one can be (bit 0) though.
But since 'one' would only be used in the default implementation of bit:
bit i = one `shiftL` i
we would get a circular definition. So we either add a 'one' method to
the class or drop the default implementation of bit and so require all
instances to define bit themselves.

I'm not sure yet which of those two options I like best.

However having zero and one as methods almost brings us overloaded
booleans. In that regard it would be better to name them false and
true though. Ideally we would split Bits into:

class Boolean b where
  false :: b
  true :: b

  -- Nice in combination with RebindableSyntax:
  ifThenElse :: b -> a -> a -> a

  -- Probably does not have to be a method:
  not :: b -> b
  not b = ifThenElse b false true

  (.&.) :: b -> b -> b
  x .&. y = ifThenElse x (ifThenElse y true) false

  (.|.) :: b -> b -> b
  x .|. y = ifThenElse x true (ifThenElse y true false)

The Bits class then becomes:

class Boolean b => Bits b where
  the (.&.), (.|.) are removed because they are defined in Boolean.

And ofcourse we would have:

instance Boolean Bool where
  false = False
  true = True
  ifThenElse c t e = if c then t else e
  (.&.) = (&&)
  (.|.) = (||)

And possibly:

instance Bits Bool where ...

And in the far future we would deprecate (&&) and (||) in favor of
(.&.) and (.|.) (or visa versa) and finally remove them.

But an important question is: is it wise to treat booleans and bits
equally? Because this would allow something like:

{-# LANGUAGE RebindableSyntax #-}

foo = if 1 then 2 else 3



More information about the Libraries mailing list