Re: [Haskell-cafe] random question

2009-10-08 Thread Nicolas Pouillard
Excerpts from Bryan O'Sullivan's message of Wed Oct 07 23:25:10 +0200 2009:
 On Wed, Oct 7, 2009 at 1:59 PM, Michael Mossey m...@alumni.caltech.eduwrote:
 
  My thread about randomness got hijacked so I need to restate my remaining
  question here. Is it acceptable to write pure routines that use but do not
  return generators, and then call several of them from an IO monad with a
  generator obtained by several calls to newStdGen?
 
  shuffle :: RandomGen g = g - [a] - [a]
  shuffle = ...
 
  foo :: [a] - [a] - IO ()
  foo xs ys = do
   g1 - newStdGen
   print $ shuffle g1 xs
   g2 - newStdGen
   print $ shuffle g2 ys
 
  Does this kind of thing exhibit good pseudorandomness?
 
 
 If you believe in the safety of the split operation (which I don't), then
  
 |
Can you elaborate on that?  -+

Best regards,

-- 
Nicolas Pouillard
http://nicolaspouillard.fr
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] random question

2009-10-07 Thread Luke Palmer
On Wed, Oct 7, 2009 at 2:59 PM, Michael Mossey m...@alumni.caltech.edu wrote:
 My thread about randomness got hijacked so I need to restate my remaining
 question here. Is it acceptable to write pure routines that use but do not
 return generators, and then call several of them from an IO monad with a
 generator obtained by several calls to newStdGen?

It's gross.  What if you don't want IO as part of this computation?

If you have a random generator that supports splitting (something
rather hard to do from what I understand), I prefer not to return the
new generator but instead to split it.  So, using your shuffle:

 shuffle :: RandomGen g = g - [a] - [a]
 shuffle = ...

foo :: RandomGen g = [a] - [a] - g - ([a],[a])
foo xs ys gen =
  let (gen1, gen2) = split gen in
  (shuffle gen1 xs, shuffle gen2 ys)

Luke
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] random question

2009-10-07 Thread Bryan O'Sullivan
On Wed, Oct 7, 2009 at 1:59 PM, Michael Mossey m...@alumni.caltech.eduwrote:

 My thread about randomness got hijacked so I need to restate my remaining
 question here. Is it acceptable to write pure routines that use but do not
 return generators, and then call several of them from an IO monad with a
 generator obtained by several calls to newStdGen?

 shuffle :: RandomGen g = g - [a] - [a]
 shuffle = ...

 foo :: [a] - [a] - IO ()
 foo xs ys = do
  g1 - newStdGen
  print $ shuffle g1 xs
  g2 - newStdGen
  print $ shuffle g2 ys

 Does this kind of thing exhibit good pseudorandomness?


If you believe in the safety of the split operation (which I don't), then
yes, since use of it is what's happening behind the scenes. In other words,
provided you're a faithful sort and split doesn't make you squirm too much,
you don't need to plug all that ugly IO in there.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] random question

2009-10-07 Thread Michael Mossey



Luke Palmer wrote:

On Wed, Oct 7, 2009 at 2:59 PM, Michael Mossey m...@alumni.caltech.edu wrote:

My thread about randomness got hijacked so I need to restate my remaining
question here. Is it acceptable to write pure routines that use but do not
return generators, and then call several of them from an IO monad with a
generator obtained by several calls to newStdGen?


It's gross.  What if you don't want IO as part of this computation?



I don't quite follow your response. I want a program that initializes the 
generator from the global generator because I want different behavior every 
time I run it. So it will need IO. That's what I was trying to demonstrate. 
And I was wondering if one can get around the difficulty of passing the 
generator from call to call by using newStdGen in this way.


Mike
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] random question

2009-10-07 Thread Daniel Fischer
Am Mittwoch 07 Oktober 2009 23:28:59 schrieb Michael Mossey:
 Luke Palmer wrote:
  On Wed, Oct 7, 2009 at 2:59 PM, Michael Mossey m...@alumni.caltech.edu 
  wrote:
  My thread about randomness got hijacked so I need to restate my
  remaining question here. Is it acceptable to write pure routines that
  use but do not return generators, and then call several of them from an
  IO monad with a generator obtained by several calls to newStdGen?
 
  It's gross.  What if you don't want IO as part of this computation?

 I don't quite follow your response. I want a program that initializes the
 generator from the global generator because I want different behavior every
 time I run it. So it will need IO. That's what I was trying to demonstrate.
 And I was wondering if one can get around the difficulty of passing the
 generator from call to call by using newStdGen in this way.

 Mike

Documentation says:

newStdGen :: IO StdGen
Applies split to the current global random generator, updates it with one of 
the results, 
and returns the other.

So it's as safe as split is.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] random question

2009-10-07 Thread Ryan Ingram
On Wed, Oct 7, 2009 at 2:28 PM, Michael Mossey m...@alumni.caltech.eduwrote:

 I don't quite follow your response. I want a program that initializes the
 generator from the global generator because I want different behavior every
 time I run it. So it will need IO. That's what I was trying to demonstrate.
 And I was wondering if one can get around the difficulty of passing the
 generator from call to call by using newStdGen in this way.


You should only have to call newStdGen once:

main = do
   g - newStdGen
   let (g1,g2) = split g
   let xs = [1..10]
   print $ shuffle g1 xs
   print $ shuffle g2 xs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-25 Thread Ariel J. Birnbaum
 And the one liner:
 (rand 1 10) = return . (\v - take v [1..10])

What about:
take $ rand 1 10 * pure [1..10]
(more readable IMHO).

One could even define:
f % x = f * pure x
and have
take $ rand 1 10 % [1..10]

Also, why not using getRandomR(1,10) instead?
take $ getRandomR (1,10) % [1..10] :: (MonadRandom m) = m Int
That way you separate the generation from the IO.

My getRandomR(0,3) % cents.
-- 
Ariel J. Birnbaum
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-25 Thread wren ng thornton

Iain Barnett wrote:

On 24 Sep 2008, at 10:13 pm, Evan Laforge wrote:
  For one approach, check
 out 'replicate' to make copies of something, and then 'sequence' to
 run them and return a list.


Thanks, I haven't found anything that explains 'sequence' well yet, but 
I'll keep looking.


Yet another explanation that might be helpful...

Consider a functor as a container (hence an |F a| value is an F-shaped 
container of values of type |a|). And remember that every monad is also 
a functor. We could imagine a value of type |F (G a)|, that is, a big 
F-shaped box containing many G-shaped boxes each containing a's. When G 
is a monad and not just a plain old functor, values of this sort are 
rather irksome to deal with because of the side effects.


But, if the functor F has certain properties[1] then it is possible to 
have a function that takes an |F (G a)| and distributes F over G to 
yield an analogous |G (F a)| value that preserves the internal 
structures of F and G. This function essentially runs a string through 
all the little |G a| beads in order to run them in some canonical 
sequence[2], it then collects their results and wraps them up in 
F-shaped boxes.


One of the places such a function is helpful is this. Consider if you 
have an |F a| value and you then fmap a monadic function |a - G b| over 
it. You now have an |F (G b)| but no simple way to get back what you 
really want: an |F b| value. If you have a function to distribute the 
functors then you can get a |G (F b)| which is a program that computes 
an |F b| subject to the state in G which it threads through each of 
those calls to that monadic function we fmapped over the |F a|.


The |sequence| function from the Prelude is exactly such a function, 
except that it fixes F to be [ ] and is only polymorphic over G and a. 
We could in principle have a more general function that doesn't force 
you to use lists. In fact, it exists as Data.Traversable.sequenceA which 
allows F to be any Data.Traversable structure and allows G to be any 
applicative functor (which are halfway between functors and monads).



[1] Namely being Data.Foldable and Data.Traversable so that we can, 
respectively, consume and reconstruct F containers. It's these 
mathematical properties we need, not the type classes themselves. 
Alternatively, if we can define for |f| a function |fsequence :: (Monad 
m) = f (m a) - m (f a)| then we can use that function to define 
instances for both of those type classes; this is what 
Data.Traversable's fmapDefault and foldMapDefault functions are about.


[2] What sequence this threading occurs in matches whatever order the 
folding function iterates over the elements in the F functor.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Lev Walkin

Iain Barnett wrote:

Hi,

I have a function, that produces a random number between two given numbers

rand :: Int - Int - IO Int
rand low high = getStdRandom (randomR (low,high))


(Naively) I'd like to write something like

take (rand 1 10 ) [1..10]

and see [1,2,3,4] ... or anything but nasty type-error messages.


myTake :: IO [Int]
myTake = do
n - rand 1 10
take n [1..10]

or

myTake = rand 1 10 = \n - take n [1..10]

or

myTake = rand 1 10 = flip take [1..10]

I'm reading about 6 tutorials on monads simultaneously but still can't 
crack this simple task, and won't pain you with all the permutations of 
code I've already tried. It's a lot, and it ain't pretty.


Would anyone be able to break away from C/C++ vs Haskell to help? Just a 
point in the right direction or a good doc to read, anything that helps 
will be much appreciated.



Monad enlightenment happens after 7'th monad tutorial. Verified by me
and a few of my friends.

--
vlm
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Lev Walkin

forgot return, of course:

 myTake :: IO [Int]
 myTake = do
 n - rand 1 10
 return $ take n [1..10]


Lev Walkin wrote:

Iain Barnett wrote:

Hi,

I have a function, that produces a random number between two given 
numbers


rand :: Int - Int - IO Int
rand low high = getStdRandom (randomR (low,high))


(Naively) I'd like to write something like

take (rand 1 10 ) [1..10]

and see [1,2,3,4] ... or anything but nasty type-error messages.


myTake :: IO [Int]
myTake = do
n - rand 1 10
take n [1..10]

or

myTake = rand 1 10 = \n - take n [1..10]

or

myTake = rand 1 10 = flip take [1..10]

I'm reading about 6 tutorials on monads simultaneously but still can't 
crack this simple task, and won't pain you with all the permutations 
of code I've already tried. It's a lot, and it ain't pretty.


Would anyone be able to break away from C/C++ vs Haskell to help? Just 
a point in the right direction or a good doc to read, anything that 
helps will be much appreciated.



Monad enlightenment happens after 7'th monad tutorial. Verified by me
and a few of my friends.



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Evan Laforge
On Wed, Sep 24, 2008 at 2:03 PM, Iain Barnett [EMAIL PROTECTED] wrote:
 Hi,

 I have a function, that produces a random number between two given numbers

 rand :: Int - Int - IO Int
 rand low high = getStdRandom (randomR (low,high))


 (Naively) I'd like to write something like

 take (rand 1 10 ) [1..10]

So once you apply those two Ints, the type of the expression is no
longer a function, it's (IO Int), which is an action that produces and
Int.  So you want to do the action 10 times.  For one approach, check
out 'replicate' to make copies of something, and then 'sequence' to
run them and return a list.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread John Van Enk
And the one liner:
(rand 1 10) = return . (\v - take v [1..10])

On Wed, Sep 24, 2008 at 5:10 PM, Lev Walkin [EMAIL PROTECTED] wrote:

 forgot return, of course:

  myTake :: IO [Int]
  myTake = do
  n - rand 1 10
  return $ take n [1..10]


 Lev Walkin wrote:

 Iain Barnett wrote:

 Hi,

 I have a function, that produces a random number between two given
 numbers

 rand :: Int - Int - IO Int
 rand low high = getStdRandom (randomR (low,high))


 (Naively) I'd like to write something like

 take (rand 1 10 ) [1..10]

 and see [1,2,3,4] ... or anything but nasty type-error messages.


 myTake :: IO [Int]
 myTake = do
n - rand 1 10
take n [1..10]

 or

 myTake = rand 1 10 = \n - take n [1..10]

 or

 myTake = rand 1 10 = flip take [1..10]

  I'm reading about 6 tutorials on monads simultaneously but still can't
 crack this simple task, and won't pain you with all the permutations of code
 I've already tried. It's a lot, and it ain't pretty.

 Would anyone be able to break away from C/C++ vs Haskell to help? Just a
 point in the right direction or a good doc to read, anything that helps will
 be much appreciated.



 Monad enlightenment happens after 7'th monad tutorial. Verified by me
 and a few of my friends.


 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe




-- 
/jve
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Iain Barnett
Your forgetfulness boosted my ego for a few seconds - I wasn't the  
only one! :)


Thanks very much, that's a big help.

Iain


On 24 Sep 2008, at 10:10 pm, Lev Walkin wrote:


forgot return, of course:

 myTake :: IO [Int]
 myTake = do
 n - rand 1 10
 return $ take n [1..10]


Lev Walkin wrote:

Iain Barnett wrote:

Hi,

I have a function, that produces a random number between two  
given numbers


rand :: Int - Int - IO Int
rand low high = getStdRandom (randomR (low,high))


(Naively) I'd like to write something like

take (rand 1 10 ) [1..10]

and see [1,2,3,4] ... or anything but nasty type-error messages.

myTake :: IO [Int]
myTake = do
n - rand 1 10
take n [1..10]
or
myTake = rand 1 10 = \n - take n [1..10]
or
myTake = rand 1 10 = flip take [1..10]
I'm reading about 6 tutorials on monads simultaneously but still  
can't crack this simple task, and won't pain you with all the  
permutations of code I've already tried. It's a lot, and it ain't  
pretty.


Would anyone be able to break away from C/C++ vs Haskell to help?  
Just a point in the right direction or a good doc to read,  
anything that helps will be much appreciated.

Monad enlightenment happens after 7'th monad tutorial. Verified by me
and a few of my friends.




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Henning Thielemann


On Wed, 24 Sep 2008, Iain Barnett wrote:


Hi,

I have a function, that produces a random number between two given numbers

rand :: Int - Int - IO Int
rand low high = getStdRandom (randomR (low,high))


If you only need arbitrary numbers, not really random ones, you should 
stay away from IO:

  http://www.haskell.org/haskellwiki/Humor/Erlk%C3%B6nig
  
http://www.haskell.org/haskellwiki/Haskell_programming_tips#Separate_IO_and_data_processing
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Iain Barnett

On 24 Sep 2008, at 10:13 pm, Evan Laforge wrote:

 For one approach, check
out 'replicate' to make copies of something, and then 'sequence' to
run them and return a list.



Thanks, I haven't found anything that explains 'sequence' well yet,  
but I'll keep looking.


On 24 Sep 2008, at 10:13 pm, John Van Enk wrote:

And the one liner:

(rand 1 10) = return . (\v - take v [1..10])



my last attempt before emailing was

(rand 1 10 ) = (\x - take x [1..10])

So close! :)

I can see now, with all the examples, why the return is needed, but  
not why the composition operator is. Something for me to look into.  
Thanks for the input.



On 24 Sep 2008, at 10:25 pm, Henning Thielemann wrote:


If you only need arbitrary numbers, not really random ones, you  
should stay away from IO:

  http://www.haskell.org/haskellwiki/Humor/Erlk%C3%B6nig
  http://www.haskell.org/haskellwiki/ 
Haskell_programming_tips#Separate_IO_and_data_processing



You're right, arbritary will be fine. It's relatively easy to get  
random numbers in other languages so I just started there, but while  
researching I had seen a few people lament the tying up of IO with  
rands, but I couldn't understand some of the other solutions  
presented. Thanks for the links, I'll give them a read.





On Wed, Sep 24, 2008 at 5:10 PM, Lev Walkin [EMAIL PROTECTED] wrote:
forgot return, of course:


 myTake :: IO [Int]
 myTake = do
 n - rand 1 10
 return $ take n [1..10]



Lev Walkin wrote:
Iain Barnett wrote:
Hi,

I have a function, that produces a random number between two given  
numbers


rand :: Int - Int - IO Int
rand low high = getStdRandom (randomR (low,high))


(Naively) I'd like to write something like

take (rand 1 10 ) [1..10]

and see [1,2,3,4] ... or anything but nasty type-error messages.

myTake :: IO [Int]
myTake = do
   n - rand 1 10
   take n [1..10]

or

myTake = rand 1 10 = \n - take n [1..10]

or

myTake = rand 1 10 = flip take [1..10]

I'm reading about 6 tutorials on monads simultaneously but still  
can't crack this simple task, and won't pain you with all the  
permutations of code I've already tried. It's a lot, and it ain't  
pretty.


Would anyone be able to break away from C/C++ vs Haskell to help?  
Just a point in the right direction or a good doc to read, anything  
that helps will be much appreciated.



Monad enlightenment happens after 7'th monad tutorial. Verified by me
and a few of my friends.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



--
/jve


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Henning Thielemann


On Wed, 24 Sep 2008, Iain Barnett wrote:


On 24 Sep 2008, at 10:13 pm, Evan Laforge wrote:

For one approach, check
out 'replicate' to make copies of something, and then 'sequence' to
run them and return a list.



Thanks, I haven't found anything that explains 'sequence' well yet, but I'll 
keep looking.


... and then replicateM

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Jonathan Cast
On Wed, 2008-09-24 at 22:44 +0100, Iain Barnett wrote:
 On 24 Sep 2008, at 10:13 pm, Evan Laforge wrote:
   For one approach, check
  out 'replicate' to make copies of something, and then 'sequence' to
  run them and return a list.

 Thanks, I haven't found anything that explains 'sequence' well yet,
 but I'll keep looking.

sequence is one of your more general-purpose loop functions in Haskell.
Frequently, the number of passes in a loop and the job of each pass are
fixed before-hand.  Standard lazy-evaluation constructs like iterate,
replicate, and map make it easy to produce a list of the passes you want
to use.  (This is the data-structure-as-control-construct pattern).
sequence then supplies the last step: it takes a list (in the principle
examples, a list of passes through some loop) and returns a loop that
goes through and executes all the passes.  In sequence, ironically
enough.

 On 24 Sep 2008, at 10:13 pm, John Van Enk wrote:
  And the one liner:

  (rand 1 10) = return . (\v - take v [1..10])

 my last attempt before emailing was

 (rand 1 10 ) = (\x - take x [1..10])

 So close! :)

 I can see now, with all the examples, why the return is needed, but
 not why the composition operator is. Something for me to look into.

Btw: the composition operator isn't needed.  You can inline it into your
example and get

(rand 1 10) = (\ v - return ((\ v - take v [1..10]) v))

(which is equivalent to the clearer

(rand 1 10) = (\ v - return (take v [1..10]))

by a step closely related to inlining (beta-contraction, to be specific)).

I don't know why composition was used in this case.  Using the version

   (\ v - take v [1..10]) $ (rand 1 10)

and using the definition

f $ a = a = return . f

gives rise to it.

jcc



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Random question

2008-09-24 Thread Brandon S. Allbery KF8NH

On 2008 Sep 24, at 17:44, Iain Barnett wrote:

On 24 Sep 2008, at 10:13 pm, Evan Laforge wrote:

 For one approach, check
out 'replicate' to make copies of something, and then 'sequence' to
run them and return a list.


Thanks, I haven't found anything that explains 'sequence' well yet,  
but I'll keep looking.


sequence turns a list of monadic values into a monadic list of values,  
i.e. [m a] becomes m [a].  In IO, this is [IO a] - IO [a].  This lets  
you do something like replicate an I/O action, then turn the list of I/ 
O actions into a single I/O action on a list.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe