Problem Set 1

Random number generation

First exercise is simple. The text says not to try to do anything fancy. Well, I'm not sure what's the opposite of fancy, but it should be my forte. Here a solution:

```fiveRands :: [Integer]
fiveRands = [
fst \$ rand \$ mkSeed 1,
fst \$ rand \$ snd \$ rand \$ mkSeed 1,
fst \$ rand \$ snd \$ rand \$ snd \$ rand \$ mkSeed 1,
fst \$ rand \$ snd \$ rand \$ snd \$ rand \$ snd \$ rand \$ mkSeed 1,
fst \$ rand \$ snd \$ rand \$ snd \$ rand \$ snd \$ rand \$ snd \$ rand \$ mkSeed 1]

```

However, it's easy to spot a common pattern in the list of function compositions. A shorter, more general version:

```fiveRands' :: [Integer]
fiveRands' = map fst \$ take 5 \$ iterate (rand . snd) \$ rand \$ mkSeed 1

```

I was initially surprised to see it working, since the first element on the array in the first defition is `fst \$ rand \$ mkSeed 1`, that is, there's no occurrence of the composite function ```(rand . snd)```. But it all makes sense if you observe the definition of `iterate`.

Random character generation

```randLetter :: Seed -> (Char, Seed)
randLetter seed = (toLetter \$ fst r, snd r)
where r = rand seed

randString3 :: String
randString3 = map fst \$ take 3 \$ iterate (randLetter . snd) \$ randLetter \$ mkSeed 1

```

More generators

```type Gen a = Seed -> (a, Seed)
myRand :: Gen Integer
myRand = rand

myRandLetter :: Gen Char
myRandLetter = randLetter

generalA :: (a -> b) -> Gen a -> Gen b
generalA f g seed = (f \$ fst r, snd r)
where r = g seed

randEven :: Gen Integer -- the output of rand * 2
randEven = generalA (\x -> x * 2) myRand

randOdd :: Gen Integer -- the output of rand * 2 + 1
randOdd = generalA (\x -> x * 2 + 1) myRand

randTen :: Gen Integer -- the output of rand * 10
randTen = generalA (\x -> x * 10) myRand

```

Generalizing random pairs

```randPair :: Gen (Char, Integer)
randPair seed = ((fst l, fst n), snd n)
where l = randLetter seed
n = rand \$ snd l

generalPair :: Gen a -> Gen b -> Gen (a, b)
-- generalPair :: (Seed -> (a, Seed)) -> (Seed -> (b, Seed)) -> Seed -> ((a,b), Seed)
generalPair gena genb seed = ((a, b), seed'')
where ra     = gena seed
a      = fst ra
seed'  = snd ra
rb     = genb seed'
b      = fst rb
seed'' = snd rb

randPair' = generalPair randLetter rand

```

Generalizing lists of generators

```repRandom :: [Gen a] -> Gen [a]
repRandom (g:gs) seed = (a : fst (repRandom gs seed'), seed')
where ra = g seed
a = fst ra
seed' = snd ra

```

```genTwo :: Gen a -> (a -> Gen b) -> Gen b
genTwo gen f seed = f a seed
where ra    = gen seed
a     = fst ra
seed' = snd ra

mkGen :: a -> Gen a
-- mkGen :: a -> Seed -> (a, Seed)
mkGen a seed = (a, seed)

```

Date: 2016-02-13 Sa 00:00

Created: 2018-09-13 Do 09:39

Validate