Рекомендуется избегать IO
всякий раз, когда вы можете, и использование монады State
предоставляет удобный способ сделать это здесь:
import Control.Applicative ((<$>))
import Control.Monad (liftM, replicateM)
import Control.Monad.State (State, evalState, get, put)
import System.Random
probablyPrime :: RandomGen g => Int -> Int -> State g Bool
probablyPrime t = liftM and . replicateM t . checkOnce
where
checkOnce :: RandomGen g => Int -> State g Bool
checkOnce n = do
(a, gen) <- randomR (3, n - 1) <$> get
put gen
return . not $ defComp a n
defComp = undefined
Чтобы проверить, является ли число (вероятно) простым, вы делаете следующее (обратите внимание, что я изменил порядок аргументов на probablyPrime
, поскольку t
с меньшей вероятностью будет отличаться от n
):
evalState (probablyPrime 10 7057) <$> newStdGen :: IO Bool
Это позволяет вам не заходить в IO
, пока это не станет абсолютно необходимым.