Haskell:随机数 - IO 操作的 Int

标签 haskell random io functional-programming monads

我最近学习了 Haskell,它的语法对我来说真的很困惑。我正在尝试使用以下方法获取 0 到 51 之间的随机数:

randomRIO (0, 51)

但我不知道如何使其成为实际的 Int (而不是 IO Int)。

我相信你应该能够做到:

gen <- randomRIO (0, 51)

然后 gen 应该是一个 Int,但我必须在 do block 中执行此操作 - 我如何创建接受此参数并返回 Int 的函数?

通过谷歌搜索,我担心有些基本内容我不明白。我完全迷失了。

最佳答案

是的,有一些基本的东西,这是新 Haskellers 遇到的最常见的问题。基本上,你说的一切都是对的,如果你想要一个返回随机 int 的“函数”,你就不能拥有它。

你可以做到

main :: IO ()
main = do
    num <- getRandomR (0, 51)
    putStrLn ("The number is " ++ show num)

你也可以把它分解出来

getCardIndex :: IO Int
getCardIndex = do
    ix <- getRandomR (0,51)
    return (ix + 1)   -- just as an example of how you can transform it

main :: IO ()
main = do
    card <- getCardIndex
    putStrLn ("The number is " ++ show card)

你不能做的就是让它成为一个纯函数/值:

pureCardIndex :: Int
pureCardIndex = ioToPure (getRandomR (0,51)) -- NOT POSSIBLE

因为没有像ioToPure这样的(道德)功能。纯函数必须始终为相同的输入返回相同的输出,而这正是您希望随机数函数执行的操作。所以我们必须使用IO来配合它。一旦您使用 IO 生成随机数,任何依赖于该随机数的东西也必须位于 IO 中。

人们会很快开始解释单子(monad)理论和所有这些,这是好东西,我只是建议耐心地接近它,在深入理论方面之前习惯这些模式。

关于Haskell:随机数 - IO 操作的 Int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48918130/

相关文章:

haskell - 模式匹配幻像类型

haskell - 如何使用Haskell的 `HashMap`?

java - 打乱排序的数组

C++生成随机数

c++ - wxDev C++ 中的 arc4random

java - 处理输入和输出时, "faster"会是什么?

c# - 使用 IO 在 C# 中读取十六进制

haskell - 树莓派 2 上的 GHCi?

haskell - 用类型相等约束固定的模棱两可的类型变量

c - 即使执行了 free 程序也会崩溃