如何处理错误"No instance for (Control.Monad.IO.Class.MonadIO [])"?

How do I deal with the error "No instance for (Control.Monad.IO.Class.MonadIO [])"?

大家晚上好!这是一个关于 Haskell 的问题。我想使用函数从列表中获取 x 个随机元素。

我遇到的问题是,当我尝试使用 randomRIO 的随机数时。我收到错误消息:

No instance for (Control.Monad.IO.Class.MonadIO [])
        arising from a use of `randomRIO'

当我使用 print 或 return 时,此错误消息突然消失。但我不想使用 print,并且 return 将输出弄乱到嵌套列表 [[a]] 而不是 [a]

你们有没有人告诉我如何以列表的形式从列表中提取 x 个随机元素?

类型应该是这样的。 xRanElems :: [a] -> Int -> [a] 其中第二个 Int 是一个累加器,但我知道了。

xRanElems xs n = do
  r <- randomRIO (0, n)
  xRanElems2 xs n r

其中 n 只是 length xs - 1

xRanElems2 xs n r = (xs !! r) : (xRanElems (xsWithOutSelectedElem xs r) (n-1))

感谢任何意见!

以下类型检查:

import System.Random

xRanElems  :: [a] -> Int -> IO [a]
xRanElems xs n = do
  -- randomRIO :: Random t 
  --           => (t, t) -> IO    t
  r <- randomRIO  (0, n)  -- r :: Int
  xRanElems2  xs      n      r    

xRanElems2 :: [a] -> Int -> Int -> IO [a]
xRanElems2 xs n r = 
   let (a,b:c) = splitAt r xs 
   in 
     fmap (b :)                --     [a] ->    [a]
          (xRanElems           --  IO [a] -> IO [a]
               (a++c) (n-1))

尝试 运行 它,例如使用 xRanElems [1..3] 2,显示它会永远循环。

这是因为您需要在 xRanElems 中提供基本情况以停止递归,例如returning []n <= 0.

以上代码还包含一个 off-by-1 错误,请您修复。