jeudi 8 août 2019

How to shuffle a list in Haskell using random selection

I am trying to shuffle a list of any a using random numbers. The reason I ask this here is because I have already made a function and I can't figure out why exactly it isn't working.

pick :: [a] -> IO a
pick xs = do
    n <- randomRIO (0, length xs - 1)
    return $ xs !! n

shuffle :: [a] -> [IO a]
shuffle ls = do
    x <- pick ls
    let y = remove x ls
    (return x) : shuffle y

-- Remove an element from a list (Only first appearance)
remove :: (Eq a) => a -> [a] -> [a]
remove _ []     = []
remove r (x:xs) = if x == r then xs else x : remove r xs

The error I get:

num.hs:31:10: error:
    * Couldn't match type `IO' with `[]'
      Expected type: [a]
        Actual type: IO a
    * In a stmt of a 'do' block: x <- pick ls
      In the expression:
        do x <- pick ls
           let y = remove x ls
           (return x) : shuffle y
      In an equation for `shuffle':
          shuffle ls
            = do x <- pick ls
                 let y = ...
                 (return x) : shuffle y
   |
31 |     x <- pick ls
   |          ^^^^^^^

What doesn't make sense to me is that it says it received a type [a] instead of IO a for pick, but ls is defined as [a]?

If there is something fundamentally wrong with this that I just don't understand, is there another way to shuffle a list in Haskell that is this simple? Preferably without any imports.




Aucun commentaire:

Enregistrer un commentaire