【发布时间】:2014-10-06 16:16:23
【问题描述】:
我是 Haskell 的新手,我正在努力实现一些相对简单的事情:生成随机数列表并将它们打印到标准输出。
由于随机概念与 FP 世界中的函数纯度完全相反(即,对于相同的输入,方法应该总是返回相同的结果),我理解在这种情况下,Haskell 中的 System.Random 模块返回 IO 操作.
到目前为止,我的代码如下所示:
import System.Random
randomNumber :: (Random a) => (a, a) -> IO a
randomNumber (a,b) = randomRIO(a,b)
main :: IO ()
main = do
points <- sequence (map (\n -> randomNumber ((-1.0), 1.0)) [1..10])
print points
这个想法很简单:生成一个包含十个随机元素的列表(可能有更好的方法来实现)。我的第一种方法是创建一个返回随机数的函数(在本例中为randomNumber,类型为IO a),并在映射元素列表时使用它(生成IO 操作列表,IO [a])。
据我了解,sequence (map (\n -> randomNumber ((-1.0), 1.0)) [1..10]) 类型是IO [a],但我不知道如何使用它。我怎样才能真正使用点作为[a] 类型的值而不是IO [a]?
编辑:在 do“块”中添加打印功能会产生一些我真的不知道如何摆脱的错误。
Main.hs:8:40:
No instance for (Random a0) arising from a use of ‘randomNumber’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Random Bool -- Defined in ‘System.Random’
instance Random Foreign.C.Types.CChar -- Defined in ‘System.Random’
instance Random Foreign.C.Types.CDouble
-- Defined in ‘System.Random’
...plus 33 others
In the expression: randomNumber ((- 1.0), 1.0)
In the first argument of ‘map’, namely
‘(\ n -> randomNumber ((- 1.0), 1.0))’
In the first argument of ‘sequence’, namely
‘(map (\ n -> randomNumber ((- 1.0), 1.0)) [1 .. 10])’
Main.hs:8:55:
No instance for (Num a0) arising from a use of syntactic negation
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus 37 others
In the expression: (- 1.0)
In the first argument of ‘randomNumber’, namely ‘((- 1.0), 1.0)’
In the expression: randomNumber ((- 1.0), 1.0)
Main.hs:8:56:
No instance for (Fractional a0) arising from the literal ‘1.0’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Fractional Double -- Defined in ‘GHC.Float’
instance Fractional Float -- Defined in ‘GHC.Float’
instance Integral a => Fractional (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus three others
In the expression: 1.0
In the expression: (- 1.0)
In the first argument of ‘randomNumber’, namely ‘((- 1.0), 1.0)’
Main.hs:9:9:
No instance for (Show a0) arising from a use of ‘print’
The type variable ‘a0’ is ambiguous
Relevant bindings include points :: [a0] (bound at Main.hs:8:9)
Note: there are several potential instances:
instance Show Double -- Defined in ‘GHC.Float’
instance Show Float -- Defined in ‘GHC.Float’
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus 65 others
In a stmt of a 'do' block: print points
In the expression:
do { points <- sequence
(map (\ n -> randomNumber ((- 1.0), 1.0)) [1 .. 10]);
print points }
In an equation for ‘main’:
main
= do { points <- sequence
(map (\ n -> randomNumber ((- 1.0), 1.0)) [1 .. 10]);
print points }
Failed, modules loaded: none.
【问题讨论】:
-
完全按照您所做的,即将结果与
<-绑定在do符号IOmonad 中。你为什么不试试print points? -
名称
points在此上下文中绑定到[a]类型的值,因为sequence ... [1..10]具有IO [a]类型。<-或“绑定”语法可以被认为是从一元上下文中“提取”一个值。在这里,你的上下文是IO,你的值的类型是[a]。 -
另外,它可能会让事情看起来更好一些:
points <- replicateM 10 (randomRIO (-1,1))。 (replicateM来自Control.Monad)。 -
points已经在[a]类型的值范围内,用于该do块中的任何内容。尝试在最后一行之后立即添加print points语句,缩进与points <- ... -
@jarandaf 写成
points <- replicateM 10 (randomRIO (-1, 1 :: Double))显式类型签名应该会有所帮助。
标签: haskell