2014-12-17 6 views
1

Это является продолжением до моего предыдущего questionСлучайное число в [0, N] в Scala

Пусть у меня есть RandomGen[A] монады. Это фактически функция: Long => (Long, A) с map и flatMap и другую функцию certain создать новый экземпляр RandomGen (как возвращение в Haskell)

class RandomGen[A](run: Long => (Long, A)) { 

    def apply(seed: Long) = run(seed) 

    def flatMap[B](f: A => RandomGen[B]): RandomGen[B] = 
    new RandomGen(seed => {val (seed1, a) = run(seed); f(a)(seed1)}) 

    def map[B](f: A => B): RandomGen[B] = 
    new RandomGen(seed => {val (seed1, a) = run(seed); (seed1, f(a))}) 
} 

def certain[A](a: A): RandomGen[A] = new RandomGen(seed => (seed, a)) 

Предположим также, у меня есть генератор случайных bits

def nextbits(bits: Int): RandomGen[Int] = ... 

Теперь я хотел бы добавить генератор , который дает случайные числа от 0 до заданного n. Я скопировал реализацию с java.util.Random и пропустил специальный случай, когда n является степенью двух для простоты.

def integer(n: Int): RandomGen[Int] = 
    nextbits(31).flatMap {r => 
    val value = r % n 
    if (r - value + (n -1) < 0) integer(n) else certain(value) 
    } 

Имеет ли смысл?

ответ

1

Да. Обратите внимание, что это всего лишь государственная монада, поэтому вы можете повторно использовать реализацию этого сказаза, если хотите. Также вы можете использовать карту вместо flatMap и избегать необходимости вызова определенного.

+0

Я не понял, как использовать 'map' i/o' flatMap'. Не могли бы вы показать код для этого? – Michael

+0

Использование монадии «State» было бы круто, но это еще одна проблема. – Michael

+0

О, моя ошибка, я пропустил рекурсию, нет, подход «flatMap» хорош. – lmm

Смежные вопросы