Type with a random value

Given this type:

data G a = G a a a

Is it possible to create a type G by giving the third field a random value without the user knowing it?

1 Like

like

newG :: a -> IO (G a)

And something from random?

1 Like
randG :: forall a. a -> a -> G a
randG x y = G x y (error "can't make this random")

but if we constrain a a little bit…

import Data.Hashable
import Data.Bits
import System.Random

randG :: forall a. Hashable a => Uniform a => a -> a -> G a
randG x y =
  let gen = mkStdGen (hash x `xor` hash y)
      (z, _) = uniform gen
   in G x y z

…then we can do it like a pure function :cowboy_hat_face:

Or you can go through IO like @Kleidukos suggests. Or you can work in some MonadRandom m. Or you can ask for a random seed as another argument.

1 Like

That function randG is no more random than “randInt x = x + 4” generates a random Int. The answer is simply “no”, you cannot create a random value in a pure function. (So you will have to use IO like Kleidukos suggested).

That’s, of course, true. It’s a pure function and therefore deterministic.

But for some definition of randomness, it is random.

If you give it an arbitrary (but not necessarily random!) Set of unique Hashable things, the resulting “random” third elements would be random.

As in, uncorrelated to the two inputs. (Assuming the hash function is good). This is a definition of randomness, and it’s one definition that actually makes sense in a pure context.

As in, pass the resulting set of random elements to dieharder and I think it’ll pass? That would be a fun exercise.

This ability to get arbitrary, deterministic randomness from unique values is super useful actually.

If you have some f :: * -> * if unique a, using a technique like this allows you to assign randomness to each element with only a Functor f instead of Traversable f (used to thread state).

In a distributed system, it allows you to make the problem of distributed randomness require no coordination. All you need is uniqueness.

Cool stuff! And @Pluto, your initial question is kind of the essence of the problem.