我正在尝试打印 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)) | ^
二三问题:
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。为了提取a从IO 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、 on1或0,或以r使其类型清晰的方式使用。通常,代码中有足够的上下文线索,您不需要像这样注释任何表达式,只要注释顶级函数即可。