Relax the restriction on Bounded derivation
Isaac Dupree
isaacdupree at charter.net
Wed Apr 18 08:02:31 EDT 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Ravi Nanavati wrote:
> On 4/17/07, Neil Mitchell <ndmitchell at gmail.com> wrote:
>>
>> Hi,
>>
>> >From Section 10 of the Haskell report, regarding automatic derivation:
>>
>> to derive Bounded for a type: "the type must be either an enumeration
>> (all constructors must be nullary) or have only one constructor."
>>
>> This seems a very artificial restriction - since it allows you to be
>> in any one of two camps, but no where in between. It also means that
>> Either doesn't derive Bounded, while it could easily do so:
>>
>> instance (Bounded a, Bounded b) => Bounded (Either a b) where
>> minBound = Left minBound
>> maxBound = Right maxBound
>>
>> So I propose that this restriction be lifted, and that the obvious
>> extension be given such that minBound is the lowest constructor with a
>> pile of minBounds, and maxBound is the highest constructor with a pile
>> of maxBound.
>
>
> In general, I like the idea of of allowing more flexible derivation of
> Bounded, but I'm worried your specific proposal ends up mandating the
> derivation of Bounded instances for types that aren't really "bounded"
> (used
> in a deliberately loose sense). Consider the following type:
>
> data Foo = A Char | B Integer | C Int
>
> On some level, there's no real problem in creating a Bounded instance as
> follows (which is how I interpret your proposal):
>
> instance Bounded Foo
> minBound = A (minBound :: Char)
> maxBound = C (maxBound :: Int)
>
> On the other hand, there's a real sense in which the type isn't actually
> "bounded". For instance, if it was also an instance of Enum, enumerating
> all
> of the values from minBound to maxBound might not terminate. I'm not sure
> what to do about the scenario. Should we (unnecessarily) insist that all of
> the arguments of all of the constructors be Bounded to avoid this? Should
> Bounded more explicitly document what properties the minBound, maxBound and
> the type should satisfy? Or something else?
IMO, Bounded only needs to satisfy (if Foo is in Ord)
forall a::Foo, a >= minBound && a <= maxBound
.
I want to be able to define bounded for
data ExtendedInteger = NegativeInfinity | PlainInteger Integer |
PositiveInfinity
. Preferably by deriving, because it's easier.
If we require properties of Enum... Enum _already_ has problems with
instances like Integer where fromEnum :: a -> Int only has a limited
possible output; there is little reasonable meaning for (fromEnum
(100000000000000000000000000000000000000000000000000000 :: Integer))
(hugs: Program error: arithmetic overflow)
(Float and Double *aren't* in Bounded. Then again, Haskell98 doesn't
require them to contain non-_|_ values of +-infinity.)
Furthermore, there are bounded things that aren't enumerable anyway (I
think) (such as some lattices), so it would be odd to add that
restriction just because the type might also be in Prelude.Enum.
However there is a good argument for having some sort of bounded-enum
class for things that have a finite number of discrete positions. These
have log(number of possibilities) information content and can (in
theory) be serialized with such a number of bits known from the type.
Designing such a class could be interesting...
Rather, I would ask "Must any inhabitant of a type in Enum be reachable
by pred or succ from an arbitrary inhabitant of the type?" For example,
I could declare an instance of Enum that contradicted that:
data Something = Some Integer | Another Integer
where pred and succ always stayed within the same constructor, and for
fromEnum/toEnum I would just find some way to encode some common (i.e.
relatively small magnitude, just as the usual instance Enum Integer is
limited this way) values of Something into an Int. Or are
fromEnum/toEnum supposed to obey some sort of properties, when they are
defined, relative to the rest of the methods? I would guess not, given
the comment
- -- NOTE: these default methods only make sense for types
- -- that map injectively into Int using fromEnum
- -- and toEnum.
(hugs: fromEnum (2.6 :: Double) ---> 2)
Cheers,
Isaac
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGJgjWHgcxvIWYTTURAlL/AJ97SilRhmd8B59TAAX+Hcyjly5oHQCff0fa
5B4Y9m0Zb3vQtilZr4lRQs0=
=Qn2+
-----END PGP SIGNATURE-----
More information about the Haskell-prime
mailing list