
Hi, I am trying to use the output value from the random function to generate the random generator for the next value in list. Below is the code - ---- import System.Random myrandoms :: (RandomGen g, Random a) => g -> [a] myrandoms gen = let (value, newGen) = random gen in value:myrandoms (mkStdGen (value::Int)) ---- however the compilation fails when the module is loaded - [1 of 1] Compiling Main ( myrandoms.hs, interpreted ) myrandoms.hs:3:80: Could not deduce (a ~ Int) from the context (RandomGen g, Random a) bound by the type signature for myrandoms :: (RandomGen g, Random a) => g -> [a] at myrandoms.hs:2:14-48 `a' is a rigid type variable bound by the type signature for myrandoms :: (RandomGen g, Random a) => g -> [a] at myrandoms.hs:2:14 Relevant bindings include value :: a (bound at myrandoms.hs:3:22) myrandoms :: g -> [a] (bound at myrandoms.hs:3:1) In the first argument of `mkStdGen', namely `(value :: Int)' In the first argument of `myrandoms', namely `(mkStdGen (value :: Int))' ---------- Even though I am converting my 'value' parameter to Int in my new generator, I am unable to see the error behind this. Please can someone explain or even better provide a fix. Thanks, Shishir

On Wed, Apr 1, 2015 at 11:08 AM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
myrandoms :: (RandomGen g, Random a) => g -> [a] myrandoms gen = let (value, newGen) = random gen in value:myrandoms (mkStdGen (value::Int))
You have declared a function that says that it can deal with any type `a` that the *caller* chooses, then provided an implementation that only supports Int. Note that :: does not do conversion (as you said "Even though I am converting my 'value' parameter to Int"); it declares that the type of `value` *is* Int. Other types will be inferred to match, and this fails at `value:` in a context which wants the type to be a caller-specified `a`, not Int. (I don't think you can coerce an unknown type `a` to Int given only the context `Random a`. You must find a different way to implement this.) -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

mkStdGen only accepts Ints as seeds. But your random function, as you typed it, can return any type of random. You either have to restrict your random function to returning ints, like so: myrandoms :: (RandomGen g) => g -> [Int] myrandoms gen = let (value, newGen) = random gen in value:myrandoms (mkStdGen value) Or you have to find a way to convert any Random a into an Int (not possible), or put another constraint on it, such that you can return all the types you might want that you have the ability to turn into ints, for example: myrandoms :: (RandomGen g, Random a, Intable a) => g -> [a] myrandoms gen = let (value, newGen) = random gen in value:myrandoms (mkStdGen $ convertToInt value) class Intable a where convertToInt :: a -> Int instance Intable Int where convertToInt = id instance Intable Integer where convertToInt = fromIntegral instance Intable Char where convertToInt s = undefined -- something Which is obviously tedious, but may be worthwhile depending on your application. On Wed, Apr 1, 2015 at 11:08 AM, Shishir Srivastava < shishir.srivastava@gmail.com> wrote:
Hi,
I am trying to use the output value from the random function to generate the random generator for the next value in list.
Below is the code -
---- import System.Random myrandoms :: (RandomGen g, Random a) => g -> [a] myrandoms gen = let (value, newGen) = random gen in value:myrandoms (mkStdGen (value::Int)) ----
however the compilation fails when the module is loaded -
[1 of 1] Compiling Main ( myrandoms.hs, interpreted )
myrandoms.hs:3:80: Could not deduce (a ~ Int) from the context (RandomGen g, Random a) bound by the type signature for myrandoms :: (RandomGen g, Random a) => g -> [a] at myrandoms.hs:2:14-48 `a' is a rigid type variable bound by the type signature for myrandoms :: (RandomGen g, Random a) => g -> [a] at myrandoms.hs:2:14 Relevant bindings include value :: a (bound at myrandoms.hs:3:22) myrandoms :: g -> [a] (bound at myrandoms.hs:3:1) In the first argument of `mkStdGen', namely `(value :: Int)' In the first argument of `myrandoms', namely `(mkStdGen (value :: Int))'
----------
Even though I am converting my 'value' parameter to Int in my new generator, I am unable to see the error behind this.
Please can someone explain or even better provide a fix.
Thanks, Shishir
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Wed, Apr 1, 2015 at 5:32 PM, David McBride
mkStdGen only accepts Ints as seeds. But your random function, as you typed it, can return any type of random. You either have to restrict your random function to returning ints, like so:
myrandoms :: (RandomGen g) => g -> [Int] myrandoms gen = let (value, newGen) = random gen in value:myrandoms (mkStdGen value)
*Is there any good reason we're not using newGen for its intended purpose here and instead weakening our randomness, maybe extremely (imagine if a list a Bool is asked for...) ???*
Or you have to find a way to convert any Random a into an Int (not possible), or put another constraint on it, such that you can return all the types you might want that you have the ability to turn into ints, for example:
myrandoms :: (RandomGen g, Random a, Intable a) => g -> [a] myrandoms gen = let (value, newGen) = random gen in value:myrandoms (mkStdGen $ convertToInt value)
class Intable a where convertToInt :: a -> Int
instance Intable Int where convertToInt = id instance Intable Integer where convertToInt = fromIntegral instance Intable Char where convertToInt s = undefined -- something
Which is obviously tedious, but may be worthwhile depending on your application.
If this was really the way Shishir wanted to go, I would suggest simply reusing the Enum typeclass rather than creating a new Intable typeclass, since : fromEnum :: (Enum a) => a -> Int Still a very bad and puzzling idea by the way... -- Jedaï
participants (4)
-
Brandon Allbery
-
Chaddaï Fouché
-
David McBride
-
Shishir Srivastava