Skip to content

Commit

Permalink
instances for Integer and Bool
Browse files Browse the repository at this point in the history
  • Loading branch information
Ingo60 committed Nov 6, 2013
1 parent bc52881 commit 6b54457
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions frege/lib/Random.fr
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ package frege.lib.Random where
class RandomGen g where
next :: g -> (Int, g)
nextLong :: g -> (Long, g)
nextBool :: g -> (Bool, g)
nextDouble :: g -> (Double, g)
split :: g -> (g,g)
genRange :: g -> (Int, Int)
genRange _ = (Int.minBound, Int.maxBound)


private data JavaGen = native java.util.Random where
protected data JavaGen = native java.util.Random where
public native new :: () -> IOMutable JavaGen
| Long -> STMutable s JavaGen
public native nextInt :: Mutable s JavaGen -> ST s Int
Expand All @@ -27,22 +29,21 @@ package frege.lib.Random where

abstract data StdGen = StdGen Long where
new i = StdGen (Int.long i)
private nextST (StdGen seed) = do
private nextST (StdGen seed) next = do
r <-JavaGen.new seed
i <- JavaGen.nextInt r
i <- next r
l <- JavaGen.nextLong r
return (i, StdGen l)
-- get the next integer and a new generator
next g = ST.run (g.nextST)
next g = ST.run (nextST g JavaGen.nextInt)
-- i have no idea if this works
split (g@StdGen seed) = (g0, g1) where
(!i,!g1) = next g
!g0 = StdGen (seed + i.long)
nextLong (StdGen seed) = ST.run do
r <- JavaGen.new seed
l1 <- JavaGen.nextLong r
l2 <- JavaGen.nextLong r
return (l1, StdGen l2)
nextLong (g@StdGen seed) = ST.run (nextST g JavaGen.nextLong)
nextBool (g@StdGen seed) = ST.run (nextST g JavaGen.nextBool)
nextDouble (g@StdGen seed) = ST.run (nextST g JavaGen.nextDouble)


instance RandomGen StdGen

Expand Down Expand Up @@ -97,3 +98,25 @@ package frege.lib.Random where
n = abs (i `mod` r) + l
!g0 = (n `band` 0xffffffffL).int
in (g0, g1)

instance Random Integer where
{--
We allow only intervals from (Long.minBound `div` 2)
to (Long.maxBound `div` 2) with the exception (Long.minBound, Long.maxBound),
which is allowed.
-}
randomR (lower,upper) g
| Long.minBound.big == lower && Long.maxBound.big == upper = case g.nextLong of
(a, g) -> case g.nextLong of
(b, g) -> case g.nextLong of
(c, g) -> case g.nextLong of
(d, g) -> ((a.big+b.big) * (c.big-d.big), g)

| otherwise = case g.nextLong of
(n, g) -> (abs n.big `rem` (upper-lower) + lower, g)

random g = randomR (Long.minBound.big, Long.maxBound.big) g

instance Random Bool where
random g = randomR (false, true) g
randomR (_,_) g = g.nextBool

0 comments on commit 6b54457

Please sign in to comment.