我试图在我创建的卡片列表中使用Data.Random.Extras包中的洗牌函数。我的代码:
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问题是,当我试图在提示符上执行generateDeck $ GHCi洗牌时,我得到的是:
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我花了几个小时的时间去寻找并试图解决/理解这个问题,但没有成功。我非常感谢你的帮助。
谢谢。
发布于 2017-01-07 16:37:14
这是因为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]或者MonadRandom的另一个实例,不涉及IO的是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]https://stackoverflow.com/questions/41523394
复制相似问题