Haskell рекурсия в IO action - PullRequest
       52

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

0 голосов
/ 22 октября 2018

Все еще новичок, который не может понять рекурсивный цикл в действии 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 ]

0 голосов
/ 22 октября 2018

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

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 ()
    }
0 голосов
/ 22 октября 2018

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и возвращает результат, полученный этим действием ввода-вывода.)

...