1

我在编写一个模拟掷骰子的函数时遇到了一些麻烦。所述骰子有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 函数的输出转换为可用格式。

提前致谢。

4

1 回答 1

2

randomRIO有 type 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

将帮助您开始。

于 2012-12-24T21:28:11.710 回答