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

标签 haskell random monads do-notation

大家晚上好!这是一个关于 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只是长度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 中提供基本案例停止递归,例如return ing []n <= 0 .

上面的代码还包含一个 off-by-1 错误,我们邀请您修复该错误。

关于haskell - 如何处理错误 "No instance for (Control.Monad.IO.Class.MonadIO [])"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71223344/

相关文章:

c++ - 从 C++ 调用 Haskell

haskell - 从 Windows 10 中完全删除 Stack

haskell - 模式匹配并非详尽无遗——为什么最后一个守卫中的 "otherwise"无法处理空列表?

Javascript坐标之间的随机数

java - 如何无限地生成随机数,直到它符合Java中的条件?

haskell - 过滤单值的无限列表

haskell - 学习Haskell : where-clause variable x, 哪里来的?

在 Java 中使用随机数时,我自己的洗牌方法中出现 Java.lang.NullPointerException?

scala - Scala 中的 Monad 变形金刚

haskell - 等式推理与喜结连理