Чтобы «спрятать» монаду ввода-вывода, нужно написать isPrime
(и любые другие функции, использующие список простых чисел) как чистую функцию и вводить ввод-вывод только настолько поздно, насколько это возможно.Тот факт, что вы используете список предварительно сгенерированных простых чисел и считывает их из файла, - это просто деталь реализации, которая не имеет отношения к общим функциям, работающим с простыми числами.
Вот простая реализация чистого isPrime
для проверки требуется целое число и список простых чисел.Обратите внимание, что не имеет значения, откуда появился список простых чисел, просто это список целых чисел.
isPrime :: Integer -> [Integer] -> Bool
isPrime n ps = n `elem` ps
Теперь давайте представим функцию, которая будет считывать простые числа с диска.Тип возвращаемого значения должен быть в монаде ввода / вывода, потому что мы выполняем ввод / вывод.
readPrimesFromFile :: String -> IO [Integer]
readPrimesFromFile filename = ...
Теперь мы можем использовать эту функцию в сочетании с нашей функцией isPrime
.Как только мы начинаем использовать readPrimesFromFile
, мы навсегда «попадаем» в монаду ввода-вывода.
main :: IO ()
main = do
primeList <- readPrimesFromFile "primes.txt"
let result = isPrime 123 primeList
print result