为什么haskell中的随机数使用randomRIO给出错误?

Rah*_*wal -2 random haskell

我正在尝试打印 0 到 1 之间的随机数,但代码出错。我无法理解我做错了什么。

import System.Random
main = print (randomRIO (1,0))
Run Code Online (Sandbox Code Playgroud)

错误: • 没有因使用“print”而产生的 (Show (IO a0)) 实例 • 在表达式中:print (randomRIO (1, 0)) 在“main”的等式中: main = print (randomRIO (1 , 0)) | 2 | main = 打印 (randomRIO (1,0)) | ^^^^^^^^^^^^^^^^^^^^^^^

错误: • 由于使用“randomRIO”而产生的歧义类型变量“a0”阻止了约束“(Random a0)”的求解。可能的解决方法:使用类型注释来指定 'a0' 应该是什么。这些潜在的实例存在: 实例随机整数——在“System.Random”实例中定义 Random Bool——在“System.Random”实例中定义 Random Char——在“System.Random”中定义......加上其他四个......加上 29 个涉及范围外类型的实例(使用 -fprint-potential-instances 查看它们) • 在 'print' 的第一个参数中,即 '(randomRIO (1, 0))' 表达式中: randomRIO (1, 0)) 在“main”的等式中: main = print (randomRIO (1, 0))

错误: • 由文字“1”引起的模糊类型变量“a0”阻止了约束“(Num a0)”的求解。可能的解决方法:使用类型注释来指定 'a0' 应该是什么。这些潜在的实例存在: instance Num Integer -- 在'GHC.Num'中定义 instance Num Double -- 在'GHC.Float'中定义 instance Num Float -- 在'GHC.Float'中定义......加上其他两个......加上 35 个涉及范围外类型的实例(使用 -fprint-potential-instances 查看它们) • 在表达式中: 1 在 'randomRIO' 的第一个参数中,即 '(1, 0)' 在第一个参数中'print',即'(randomRIO (1, 0))' | 2 | main = 打印 (randomRIO (1,0)) | ^

luq*_*qui 6

二三问题:

print randomRIO (1,0)
Run Code Online (Sandbox Code Playgroud)

读起来就像print给了两个参数的函数。或者,从技术上讲,由于应用程序是左关联的,它的含义与此相同:

(print randomRIO) (1,0)
Run Code Online (Sandbox Code Playgroud)

如果您只想给出print一个参数,则必须将其括起来:

print (randomIO (1,0))
Run Code Online (Sandbox Code Playgroud)

但这给我们带来了第二个问题。 randomRIO是一个IO 动作,而不是一个简单的函数。它的类型(专门用于教育目的)是

randomRIO :: (Int, Int) -> IO Int
Run Code Online (Sandbox Code Playgroud)

请注意,返回值的格式为IO something? randomRIO (1,0)IO Int,但我们想打印一个普通的Int。为了提取aIO a,则结合的功能中的可变do块:

main = do
    r <- randomRIO (1,0)
    print r
Run Code Online (Sandbox Code Playgroud)

我以为就是这样,但是(如果你不像我那样在 ghci 中这样做)你会得到一个模棱两可的类型变量警告,因为randomRIO不知道你是想选择一个随机的Int还是随机的Double还是什么,然后简单地打印它不足以推断出这一点。所以我们必须指定:

main = do
    r <- randomRIO (1, 0)
    print (r :: Int)
Run Code Online (Sandbox Code Playgroud)

(想想你可能Double无论如何都想要一个。)

我们可以用很多不同的方式指定类型;on r、 on10,或以r使其类型清晰的方式使用。通常,代码中有足够的上下文线索,您不需要像这样注释任何表达式,只要注释顶级函数即可。