Haskell рекурсия в IO action

Все еще начинающий, который не может понять рекурсивный цикл в IO действие. Предполагать:

fMinInspect :: Int
fMinInspect = 1
fMaxInspect :: Int
fMaxInspect = 12
-- fNoInspectPerHour :: IO ()
fNoInspectPerHour = do
  generateInspect <- randomRIO (fMinInspect,fMaxInspect)
  putStrLn ""

Я хотел бы создать список для, скажем, 10 машин, которые я хочу проверить случайным образом, могу ли я сделать повторный вызов чего-то, что добавит 10x fNoInspectPerHour в список?

Я пробовал внешнюю функцию, но не могу получить действия от IO (), Обратите внимание, что putStrLn это просто прекратить do-блок, так как мне не нужен консольный вывод.

PS. предложения о прекращении doблок без putStrLn тоже приветствуется

2 ответа

Решение

Если вы действительно хотите использовать рекурсию здесь, вы можете написать, например,

fNoInspectPerHour :: Int -> IO () 
fNoInspectPerHour 0 = return () 
fNoInspectPerHour n = do { 
    generateInspect <- randomRIO (fMinInspect,fMaxInspect) ; 
    --  Int            IO Int
    putStrLn generateInspect ;    -- or do some other IO action
    --                 IO ()
    fNoInspectPerHour (n-1) 
    --                 IO ()
    }

randomIO (fMinInspect, fMaxInspect) это действие ввода-вывода, значение типа (Num a, Random a) => IO a, (Для простоты предположим, что a является Int с этого момента.) Обратите внимание, что при каждом выполнении действия может генерироваться другое случайное значение; в этом разница между IO Int быть действием, которое генерирует случайное значение, и само является случайным значением.

Как только мы выполним это действие, мы можем создать список действий с replicate 10 (randomRIO (fMinInspect, fMaxInspect)); это будет иметь тип [IO Int]10 копий действий ввода-вывода.

sequence Функция может изменить ваш список действий ввода-вывода в действие ввода-вывода, которое выдает список значений (каждое значение создается соответствующим действием), преобразовывая значение типа [IO Int] в значение типа IO [Int],

> fMinInspect = 1
> fMaxInspect = 12
> sequence (replicate 10 (randomRIO (fMinInspect, fMaxInspect)))
[1,6,6,1,7,5,8,4,7,7]

(Здесь, как обычно, GCHi выполняет действие ввода-вывода, которое было произведено sequenceи возвращает результат, полученный этим действием ввода-вывода.)

Другие вопросы по тегам