1

サイコロのロールをシミュレートする関数を書くのに少し問題があります。このサイコロには 6 つの面があり、その上に 1 ~ 5 と W があります。1 は 1 ポイントの価値があり、2 は 2 ポイントの価値があります。しかし、W は 5 点の価値があります。Char 値と Int ポイントを持つデータ型 Side を作成しました。6 つの面すべてを保存する 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モナド内でのみRandomRIOを使用する必要があることをどこかで読んだことがありますが、スローされた側をリストに追加してから、そのリスト内の側のすべての値を表示する必要があり、変換方法が完全にわかりませんRandomRIO 関数の出力を使用可能な形式に変換します。

前もって感謝します。

4

1 に答える 1

2

randomRIOタイプRandom a => (a, a) -> IO aが、結果値がIOモナドにトラップされることを意味します。IOモナドはエスケープできないため、ランダムな値を使用する場合は、関数がIOバウンドタイプの値も返す必要があります(同じ入力が同じ出力を生成しない場合、関数は純粋ではありません)。

私は次のようなものを願っています

import Control.Monad (replicateM)
import System.Random 

main = do
    randList <- replicateM yourListSize (randomRIO (1,6))
    print randList

始めるのに役立ちます。

于 2012-12-24T21:28:11.710 に答える