Data.Random.Extras 用法
Data.Random.Extras Usage
我正在尝试使用来自 Data.Random.Extras 的 shuffle 函数我创建的卡片列表中的包。我的代码:
module Cards where
import Data.Random.Extras
data Suit = Clubs
| Diamonds
| Hearts
| Spades
deriving (Eq,Enum,Ord,Show,Bounded)
data Value = Two
| Three
| Four
| Five
| Six
| Seven
| Eight
| Nine
| Ten
| Jack
| Queen
| King
| Ace
deriving (Eq,Enum,Ord,Show,Bounded)
data Card = Card Value Suit
deriving (Eq,Ord,Show)
type Deck = [Card]
-- Generate deck of cards
generateDeck :: Deck
generateDeck = [Card val suit | suit <- [Clubs .. Spades], val <- [Two .. Ace]]
-- Print deck of cards
printDeck :: Deck -> IO ()
printDeck deck = putStr (formatDeck deck)
where
formatDeck [] = []
formatDeck (x:xs) = (show x) ++ "\n" ++ formatDeck xs
问题是,当我尝试在 GHCi 提示符下执行 shuffle $ generateDeck 时,我得到:
No instance for (Show (Data.RVar.RVar [Card]))
arising from use of 'print'
Possible fix:
Add an instance declaration for (Show (Data.RVar.RVar [Card]))
In a stmt of an interactive GHCi command: print it
我花了几个小时搜索并尝试 solve/understand 但没有成功。非常感谢您的帮助。
谢谢。
那是因为shuffle
的类型是[a] -> RVar [a]
。因此,您不会取回可以直接使用的 [a]
,而是一些神秘的 RVar
。 RVar
有点像 IO
,因为 RVar a
不是类型 a
的值,而更像是获取类型 a
的值。为了实际获得类型 a
的值,您必须使用 runRVar :: RandomSource m s => RVar a -> s -> m a
。查看 RandomSource
的文档,有多个实例。一个例子是 MonadRandom m => RandomSource m StdRandom
。所以我们可以这样使用runRVar
(因为IO
是MonadRandom
的一个实例):
> import Data.Random (runRVar, StdRandom(..))
> import Data.Random.Extras (shuffle)
> runRVar (shuffle [1..10]) StdRandom :: IO [Int]
[3,10,8,5,6,7,4,2,9,1]
或者不涉及 IO
的 MonadRandom
的另一个实例是 State StdGen a
:
> -- Above imports and
> import Control.Monad.State (State,evalState)
> import System.Random (StdGen,mkStdGen)
> shuffledState = runRVar (shuffle [1..10]) StdRandom :: State StdGen [Int]
> evalState shuffledState $ mkStdGen 0 -- 0 is the seed
[6,8,7,5,10,9,2,3,1,4]
我正在尝试使用来自 Data.Random.Extras 的 shuffle 函数我创建的卡片列表中的包。我的代码:
module Cards where
import Data.Random.Extras
data Suit = Clubs
| Diamonds
| Hearts
| Spades
deriving (Eq,Enum,Ord,Show,Bounded)
data Value = Two
| Three
| Four
| Five
| Six
| Seven
| Eight
| Nine
| Ten
| Jack
| Queen
| King
| Ace
deriving (Eq,Enum,Ord,Show,Bounded)
data Card = Card Value Suit
deriving (Eq,Ord,Show)
type Deck = [Card]
-- Generate deck of cards
generateDeck :: Deck
generateDeck = [Card val suit | suit <- [Clubs .. Spades], val <- [Two .. Ace]]
-- Print deck of cards
printDeck :: Deck -> IO ()
printDeck deck = putStr (formatDeck deck)
where
formatDeck [] = []
formatDeck (x:xs) = (show x) ++ "\n" ++ formatDeck xs
问题是,当我尝试在 GHCi 提示符下执行 shuffle $ generateDeck 时,我得到:
No instance for (Show (Data.RVar.RVar [Card]))
arising from use of 'print'
Possible fix:
Add an instance declaration for (Show (Data.RVar.RVar [Card]))
In a stmt of an interactive GHCi command: print it
我花了几个小时搜索并尝试 solve/understand 但没有成功。非常感谢您的帮助。
谢谢。
那是因为shuffle
的类型是[a] -> RVar [a]
。因此,您不会取回可以直接使用的 [a]
,而是一些神秘的 RVar
。 RVar
有点像 IO
,因为 RVar a
不是类型 a
的值,而更像是获取类型 a
的值。为了实际获得类型 a
的值,您必须使用 runRVar :: RandomSource m s => RVar a -> s -> m a
。查看 RandomSource
的文档,有多个实例。一个例子是 MonadRandom m => RandomSource m StdRandom
。所以我们可以这样使用runRVar
(因为IO
是MonadRandom
的一个实例):
> import Data.Random (runRVar, StdRandom(..))
> import Data.Random.Extras (shuffle)
> runRVar (shuffle [1..10]) StdRandom :: IO [Int]
[3,10,8,5,6,7,4,2,9,1]
或者不涉及 IO
的 MonadRandom
的另一个实例是 State StdGen a
:
> -- Above imports and
> import Control.Monad.State (State,evalState)
> import System.Random (StdGen,mkStdGen)
> shuffledState = runRVar (shuffle [1..10]) StdRandom :: State StdGen [Int]
> evalState shuffledState $ mkStdGen 0 -- 0 is the seed
[6,8,7,5,10,9,2,3,1,4]