Random variable holding a function

Hi I try to simulate some processes, that contain randomness and I would like do it idiomatic way and keep as much code not to know about randomness as possible. I have a following code (simplified to make email more readable): import Data.List import Data.Functor import Genes import Data.Random.RVar import Data.Random.Extras data Individual = Individual (Int, Int) deriving (Eq, Show) -- this part is a bit more complicated... data Population = Population { individuals :: [Individual] } deriving (Eq, Show) type Selection = Population -> Population so far, it's easy: allSurvive :: Selection allSurvive = id extinction :: Selection extinction _ = Population [] The issue comes, when I want to have some randomness in the process. I am able to write a "pick some individuals into next generation" sort of "Selection" fairChance :: Int -> Population -> RVar Population fairChance newSize p = Population <$> (Data.Random.Extras.sample newSize $ individuals p) But it obviously doesn't fit into the "Selection" type. I would like to have something like fairChance :: Int -> RVar Selection (e.g. fairChance :: Int -> RVar (Population -> Population)) Is there a way to do this? Or should I give up this way and try to give up some purity and go withtype Selection :: RVar Population -> RVar population? Thanks Ondrej

On 2015-02-26 at 12:42, Ondrej Nekola
type Selection = Population -> Population
so far, it's easy:
allSurvive :: Selection allSurvive = id
fairChance :: Int -> Population -> RVar Population fairChance newSize p = Population <$> (Data.Random.Extras.sample newSize $ individuals p)
fairChance :: Int -> RVar Selection (e.g. fairChance :: Int -> RVar (Population -> Population))
Is there a way to do this? Or should I give up this way and try to give up some purity and go withtype Selection :: RVar Population -> RVar population?
Thanks Ondrej _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On 2015-02-26 at 12:42, Ondrej Nekola
type Selection = Population -> Population
so far, it's easy:
allSurvive :: Selection allSurvive = id
fairChance :: Int -> Population -> RVar Population fairChance newSize p = Population <$> (Data.Random.Extras.sample newSize $ individuals p)
fairChance :: Int -> RVar Selection (e.g. fairChance :: Int -> RVar (Population -> Population))
Is there a way to do this? Or should I give up this way and try to give up some purity and go withtype Selection :: RVar Population -> RVar population?
I would define Selection as | type Selection = Population -> RVar Population Then you can compose with >>=, which specializes to | (>>=) :: RVar Population -> Selection -> RVar Population or with any of the other Monad operators (eg, >=>). With this definition, you can keep your current definition of fairChance. There's no problem defining values of type `RVar (Population -> Population`. `fmap allSurvive` is one such. But defining fairChance this way seems a bit awkward to me. Daniel

Thank you, it was very helpfull. For reference, this is the code, that reflect Daniel's recommendation (I hope I made no stupid mistake there): https://github.com/satai/FrozenBeagle/blob/32f22979d7ef8d5265aa9e49982fa394e... Thanks Ondrej
On 2015-02-26 at 12:42, Ondrej Nekola
wrote: type Selection = Population -> Population
so far, it's easy:
allSurvive :: Selection allSurvive = id
fairChance :: Int -> Population -> RVar Population fairChance newSize p = Population <$> (Data.Random.Extras.sample newSize $ individuals p)
fairChance :: Int -> RVar Selection (e.g. fairChance :: Int -> RVar (Population -> Population))
Is there a way to do this? Or should I give up this way and try to give up some purity and go withtype Selection :: RVar Population -> RVar population? I would define Selection as
| type Selection = Population -> RVar Population
Then you can compose with >>=, which specializes to
| (>>=) :: RVar Population -> Selection -> RVar Population
or with any of the other Monad operators (eg, >=>).
With this definition, you can keep your current definition of fairChance.
There's no problem defining values of type `RVar (Population -> Population`. `fmap allSurvive` is one such. But defining fairChance this way seems a bit awkward to me.
Daniel

Daniel Bergey wrote:
On 2015-02-26 at 12:42, Ondrej Nekola
wrote: I try to simulate some processes, that contain randomness and I would like do it idiomatic way and keep as much code not to know about randomness as possible.
type Selection = Population -> Population
so far, it's easy:
allSurvive :: Selection allSurvive = id
fairChance :: Int -> Population -> RVar Population fairChance newSize p = Population <$> (Data.Random.Extras.sample newSize $ individuals p)
fairChance :: Int -> RVar Selection (e.g. fairChance :: Int -> RVar (Population -> Population))
Is there a way to do this? Or should I give up this way and try to give up some purity and go withtype Selection :: RVar Population -> RVar population?
I would define Selection as
| type Selection = Population -> RVar Population
Then you can compose with >>=, which specializes to
| (>>=) :: RVar Population -> Selection -> RVar Population
or with any of the other Monad operators (eg, >=>).
With this definition, you can keep your current definition of fairChance.
This is pretty much the "probability monad". For more on this, my personal recommendations would be http://apfelmus.nfshost.com/articles/random-permutations.html http://web.engr.oregonstate.edu/~erwig/papers/PFP_JFP06.pdf Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com
participants (3)
-
Daniel Bergey
-
Heinrich Apfelmus
-
Ondrej Nekola