Итак, моя цель - вызвать немонодическую функцию и вернуть ее случайное значение.Получение случайных чисел из немонодических функций
getNums :: [Int] -- this only works when the type signature is "IO [Int]"
getNums = getListFromIO 10
getListFromIO :: Int -> IO [Int]
getListFromIO n = do
gen <- newStdGen
return $ generateList n gen
generateList :: Int -> StdGen -> [Int]
generateList n gen = take n $ randomRs (1,9) $ gen
Если я позвоню getListFromIO
, все будет хорошо; Я получаю свой драгоценный случайный список целых чисел, и каждый раз он отличается. Но каждая функция, которая его вызывает, должна использовать IO [Int]
это подпись типа. Я не хочу этого.
Как я могу структурировать это, чтобы получить случайный список номеров типа [Int]
?
Вы не можете. Вся цель типа «IO» заключается в том, чтобы вы не могли этого сделать. Если вы * можете *, это нарушит ваши программы. Вместо этого вы должны спросить, как использовать 'getNums :: IO [Int]' таким образом, чтобы вы могли работать с значением '[Int]', которое оно вычисляет в ваших других функциях. Это то, для чего нужны методы типа Monad и 'Functor'. –
Если вы чувствуете себя авантюрно, вы можете использовать ['unsafePerformIO'] (https://hackage.haskell.org/package/base-4.0.0.0/docs/System-IO-Unsafe.html). Обратите внимание на ** небезопасный бит **. – fjarri
Пожалуйста, не рекомендуем 'unsafePerformIO' тем, кто не понимает опасных последствий его использования или идиоматического способа написания Haskell без него. Это вредно. –