[Haskell-beginners] Type-class instance for any type that has an instance of another type
Brent Yorgey
byorgey at seas.upenn.edu
Tue May 24 14:58:14 CEST 2011
On Tue, May 24, 2011 at 08:54:05PM +1000, Arlen Cuss wrote:
> Hi all,
>
> I may be a liiittle in over my head. I'm trying to make a type-class for
> a type that can be "randomly generated". The class looks like this:
>
> > class RandomlyGeneratable a where
> > rgen :: IO a
>
> So far so good. Now, I'd love to be able to define an instance of this
> on all types that have Enum, because the definition is not hard:
>
> > instance Enum a => RandomlyGeneratable a where
> > rgen = fmap (opts !!) $ randomRIO (0,pred (length opts))
> > where opts = enumFrom $ (toEnum 0) :: a
>
> Unfortunately I'm wording this incorrectly, as the "instance" line
> produces:
>
> Illegal instance declaration for `RandomlyGeneratable a'
> (All instance types must be of the form (T a1 ... an)
> where a1 ... an are *distinct type variables*,
> and each type variable appears at most once in the instance head.
> Use -XFlexibleInstances if you want to disable this.)
> In the instance declaration for `RandomlyGeneratable a'
Actually there wasn't much wrong with your syntax here, it's just that
the basic Haskell standard is quite rigid in terms of what sorts of
instances are accepted. If you turned on the flag -XFlexibleInstances
(which is quite uncontroversial and widely supported) as the error
message suggests, it would work fine.
However, with this instance you would not able to make any other
RandomlyGeneratable instances -- essentially the instance says "any
type a is an instance of RandomlyGeneratable, and it is an error if
the type a is not an instance of Enum". So for that reason the
newytpe approach (what you wrote in your second email) is to be
preferred.
By the way, such a class already exists -- it is called Random [1].
But if you are just doing this as a learning exercise, then go right
ahead.
-Brent
[1] http://hackage.haskell.org/packages/archive/random/latest/doc/html/System-Random.html#t:Random
More information about the Beginners
mailing list