我在编写模拟掷骰子的功能时遇到了一些麻烦。 所述骰子有6个侧面,上面有1-5和W。 1值1点,2点值2点,依此类推。但W值得5分。 我创建了一个数据类型Side,具有Char值和Int点。我生成一个intMap,我保存所有六个边,然后我使用一个函数rollDice,它应该返回一个随机的。
像这样:
module Dice where
import qualified Data.IntMap as IM
import System.Random
data Side = Side {
value :: Char,
points :: Int
} deriving Show
data Dice = Dice (IM.IntMap (Side))
dice = Dice $ IM.fromList[(0,Side '1' 1),(1,Side '2' 2),
(2 ,Side '3' 3),(3,Side '4' 4),
(4,Side '5' 5),(5,Side 'W' 5)]
throwDice :: Dice -> Side
throwDice (Dice (intMap)) = intMap IM.!(randomRIO (1,6 :: Int))
在尝试加载时返回以下错误:
Dice.hs:22:41:
Couldn't match expected type `IM.Key' with actual type `IO a0'
In the return type of a call of `randomRIO'
In the second argument of `(IM.!)', namely
`(randomRIO (1, 6 :: Int))'
In the expression: intMap IM.! (randomRIO (1, 6 :: Int))
我在某处读过你应该只在IO monad中使用RandomRIO,但是我需要将抛出的一边附加到一个列表然后显示该列表中所有边的值,我完全迷失了如何将RandomRIO函数的输出转换为可用的格式。
提前致谢。
答案 0 :(得分:2)
randomRIO
的类型为Random a => (a, a) -> IO a
,这意味着结果值被捕获到IO monad。 IO monad无法转义,因此如果要使用随机值,您的函数也必须返回IO绑定类型的值(如果相同的输入不产生相同的输出,则函数不能是纯的)
我希望像
这样的东西import Control.Monad (replicateM)
import System.Random
main = do
randList <- replicateM yourListSize (randomRIO (1,6))
print randList
将帮助您开始。