Re: type classes and generality
On 09-Jul-2001, Norman Ramsey <nr@eecs.harvard.edu> wrote:
I'm trying to model probability and leave the representation of probability unspecified other than it must be class Real. But I'm having trouble with random numbers; how can I show that if a type has class Real, it also has class Random.Random? Is there a way to accomplish this goal other than by changing the library?
I'm not sure if I fully understand your goal. But one thing you can do is to define a wrapper type
newtype WrapReal r = WrapReal r
and make the wrapper an instance of Random.Random if the underlying type is an instance of Real
instance Real r => Random.Random (WrapReal r) where ...
Then you can use the wrapper type whenever you want to get a random number.
The problem is that without intensional type analysis, I wouldn't know how to fill in the instance methods in the `...' N
On 09-Jul-2001, Norman Ramsey <nr@eecs.harvard.edu> wrote:
On 09-Jul-2001, Norman Ramsey <nr@eecs.harvard.edu> wrote:
I'm trying to model probability and leave the representation of probability unspecified other than it must be class Real. But I'm having trouble with random numbers; how can I show that if a type has class Real, it also has class Random.Random? Is there a way to accomplish this goal other than by changing the library?
I'm not sure if I fully understand your goal. But one thing you can do is to define a wrapper type
newtype WrapReal r = WrapReal r
and make the wrapper an instance of Random.Random if the underlying type is an instance of Real
instance Real r => Random.Random (WrapReal r) where ...
Then you can use the wrapper type whenever you want to get a random number.
The problem is that without intensional type analysis, I wouldn't know how to fill in the instance methods in the `...'
How about like so? import Random newtype WrapReal r = WrapReal r wrap r = WrapReal r unwrap (WrapReal r) = r instance Real r => Random (WrapReal r) where random = randomR (wrap 0, wrap 1) randomR (min, max) gen0 = (wrap (fromInteger r), gen) where (r, gen) = randomR (imin, imax) gen0 imin = ceiling (toRational (unwrap min)) imax = floor (toRational (unwrap max)) Ah, now I think I understand your problem. You want to `random' to generate random numbers that span all the possible values of the type within the range [0, 1], or at least a substantial subset, but the "Real" class doesn't let you generate any numbers other than integers. The above approach will give you random numbers from `random', but they will only ever be 0 or 1, so maybe they are not as random as you needed! ;-) The proof that you can only generate integers values of the real type (by which I mean values of the real type for which toRational returns an integer) is that the only methods of class Real which return values of the type are "fromInteger", and the operators ("+", "*", "-", "negate", "abs", and "signum"), which are all integer-preserving -- when given integers they will always return other integers. So by induction you can't generate any non-integers. I'd advise you to add an extra "Random t" class constraint to those parts of your application that rely on generating random numbers. If you find yourself using `Real t, Random t' frequently, you can use a derived class for that: class (Random t, Real t) => RandomReal a where -- no methods -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit The University of Melbourne | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
Hi All, Fergus Henderson wrote:
Ah, now I think I understand your problem. You want to `random' to generate random numbers that span all the possible values of the type within the range [0, 1], or at least a substantial subset, but the "Real" class doesn't let you generate any numbers other than integers. The above approach will give you random numbers from `random', but they will only ever be 0 or 1, so maybe they are not as random as you needed! ;-)
Each pseudorandom generator generates a countable sequence of values, which is isomorphic to a sequence of integers. In good old (Turbo)C we got something between 0 and MAXINT and then divided by (double)MAXINT. Can't _this_ be done in Haskell? Alexander
On 09-Jul-2001, Alexander V. Voinov <avv@quasar.ipa.nw.ru> wrote:
Hi All,
Fergus Henderson wrote:
Ah, now I think I understand your problem. You want to `random' to generate random numbers that span all the possible values of the type within the range [0, 1], or at least a substantial subset, but the "Real" class doesn't let you generate any numbers other than integers. The above approach will give you random numbers from `random', but they will only ever be 0 or 1, so maybe they are not as random as you needed! ;-)
Each pseudorandom generator generates a countable sequence of values, which is isomorphic to a sequence of integers. In good old (Turbo)C we got something between 0 and MAXINT and then divided by (double)MAXINT. Can't _this_ be done in Haskell?
Sure, it can be done, but not on a value whose type is constrained only by the "Real" class, because the "Real" class doesn't have any division operator! Haskell's "/" operator is a member of the "Floating" class, and "Floating" is not a base class of "Real". It is a base class of the "RealFrac" class, so you could use that approach for "RealFrac"... but the original poster was asking for the solution to a more difficult problem. -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit The University of Melbourne | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
"Alexander V. Voinov" wrote:
Hi All,
Fergus Henderson wrote:
Ah, now I think I understand your problem. You want to `random' to generate random numbers that span all the possible values of the type within the range [0, 1], or at least a substantial subset, but the "Real" class doesn't let you generate any numbers other than integers. The above approach will give you random numbers from `random', but they will only ever be 0 or 1, so maybe they are not as random as you needed! ;-)
Each pseudorandom generator generates a countable sequence of values, which is isomorphic to a sequence of integers. In good old (Turbo)C we got something between 0 and MAXINT and then divided by (double)MAXINT. Can't _this_ be done in Haskell?
Of course it can be done, but not in class Real, you have to be in Fractional. I'm not sure why Real would be the class of choice for this problem anyway. I'd think that Fractional or RealFrac would be more appropriate. -- Lennart
Hi All, Lennart Augustsson wrote:
Each pseudorandom generator generates a countable sequence of values, which is isomorphic to a sequence of integers. In good old (Turbo)C we got something between 0 and MAXINT and then divided by (double)MAXINT. Can't _this_ be done in Haskell?
Of course it can be done, but not in class Real, you have to be in Fractional. I'm not sure why Real would be the class of choice for this problem anyway. I'd think that Fractional or RealFrac would be more appropriate.
I apologize for ignorance, I probably did not read this part of the doc attentively. But informally, the word 'Real' is widely used to denote a completely ordered field, and there is a theorem to change 'a' to 'the'. It's counterintuitive to use Real in any other meaning, I think. Alexander
"Alexander V. Voinov" wrote:
Hi All,
Lennart Augustsson wrote:
Each pseudorandom generator generates a countable sequence of values, which is isomorphic to a sequence of integers. In good old (Turbo)C we got something between 0 and MAXINT and then divided by (double)MAXINT. Can't _this_ be done in Haskell?
Of course it can be done, but not in class Real, you have to be in Fractional. I'm not sure why Real would be the class of choice for this problem anyway. I'd think that Fractional or RealFrac would be more appropriate.
I apologize for ignorance, I probably did not read this part of the doc attentively. But informally, the word 'Real' is widely used to denote a completely ordered field, and there is a theorem to change 'a' to 'the'. It's counterintuitive to use Real in any other meaning, I think.
I agree. -- Lennart
participants (4)
-
Alexander V. Voinov -
Fergus Henderson -
Lennart Augustsson -
Norman Ramsey