2016-02-18 2 views
0

Я новичок в haskell, и я пытался выяснить эту проблему на некоторое время. Я хочу сгенерировать список случайного размера с помощью randomRIO, и этот список будет заполнен случайными числами с помощью randomIO. Я попытался подойти к этой проблеме, создав функцию, которая принимает в случайно сгенерированных из randomRIO так:Как создать беспорядочно отсортированный список случайных чисел в Haskell

x <- randomRIO(1,5) 
let y = randList x [] 

сама функция что-то вроде этого:

randList :: Int -> IO [Int] -> IO [Int] 
randList 0 xs = return [xs] 
randList g xs = do 
      t <- randomIO 
      let a = t:randList (g-1) xs 
      return [a] 

Я не знаю, как для обработки монады IO в рекурсивной функции, но именно так я об этом думаю. Любая помощь приветствуется!

+0

Обратите внимание, что это сильно избегали в Haskell, чтобы положить что-то подобное в 'IO'. Лучше принять явный аргумент «RandomGen» (или использовать специализированную монаду, которая делает именно это). – leftaroundabout

ответ

4

Вы можете использовать replicateM для повторного выполнения randomIO, генерируя новый номер каждый раз. Вы называете randomRIO раз вперед, чтобы принять решение о длине списка:

import Control.Monad (replicateM) 
import System.Random (randomIO, randomRIO) 

randList :: IO [Int] 
randList = do 
    len <- randomRIO (1,5) 
    replicateM len randomIO 

Теперь, ваше определение не было на самом деле очень далеко. Несколько вещей, хотя:

  • Учитывая, что вы ожидаете, чтобы быть в состоянии назвать randList x [], второй аргумент randList явно представляет собой обычный список. Это не какое-то действие. Так что ваш тип должен быть

    randList :: Int -> [Int] -> IO [Int] 
    
  • В своем первом матче шаблон

    randList 0 xs = return [xs] 
    

    Помните, что xs уже список. Поэтому, когда вы делаете return [xs], вы получите IO [[Int]], список списков. Здесь вы можете найти простой return xs.

  • В вашем втором определении

    randList g xs = do 
        t <- randomIO 
        let a = t:randList (g-1) xs 
        return [a] 
    

    Выражение t:randList ... не имеет никакого смысла. Правой частью : должен быть список. randList не дает списка, хотя он дает действие IO. То, что вы на самом деле хотите сделать, - это обработать второй аргумент randList (список) в качестве «аккумулятора», который постепенно создается. Итак, вы хотите, чтобы сгенерировать номер, добавить его к аккумулятору, а затем рекурсивный с g снизился на один:

    randList g xs = do 
        t <- randomIO 
        randList (g-1) (t:xs) 
    
+0

Это было действительно полезно, спасибо вам большое! Быстрый вопрос. Есть ли место для разделения чисел с помощью «,», как в обычном списке? *** РЕДАКТОРА: Не обращайте внимания, я получил список несколько раз случайно. Еще раз спасибо!! – Chris

Смежные вопросы