Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 哈斯克尔:洗牌牌组_Loops_Haskell_Random_Shuffle - Fatal编程技术网

Loops 哈斯克尔:洗牌牌组

Loops 哈斯克尔:洗牌牌组,loops,haskell,random,shuffle,Loops,Haskell,Random,Shuffle,我在一个实验室里工作,在那里我们处理随机性和单子 实验室的组成部分包括: 编写一个函数randR,生成给定范围内的随机数 编写一个函数rolltowdice,模拟滚动两个骰子 编写一个函数removeCard,该函数从播放卡列表中随机删除一张卡 编写一个函数shuffleDeck,它将取出的牌放在牌组前面,然后重复它自己,直到牌组完全洗牌 我已经完成了1、2和3,但我在4方面遇到了问题 以下是给定的代码: RandState.hs module RandState where import UC

我在一个实验室里工作,在那里我们处理随机性和单子

实验室的组成部分包括:

  • 编写一个函数randR,生成给定范围内的随机数
  • 编写一个函数rolltowdice,模拟滚动两个骰子
  • 编写一个函数removeCard,该函数从播放卡列表中随机删除一张卡
  • 编写一个函数shuffleDeck,它将取出的牌放在牌组前面,然后重复它自己,直到牌组完全洗牌
  • 我已经完成了1、2和3,但我在4方面遇到了问题

    以下是给定的代码:

    RandState.hs

    module RandState where
    import UCState
    import System.Random
    
    -- In order to generate pseudo-random numbers, need to pass around generator
    --  state in State monad
    type RandState a = State StdGen a
    
    -- runRandom runs a RandState monad, given an initial random number generator
    runRandom :: RandState a -> StdGen -> a
    runRandom (State f) s = res
        where (res, state) = f s
    
    -- rand is a helper function that generates a random instance of any
    --  type in the Random class, using the RandState monad.
    rand :: Random a => RandState a
    rand = do
        gen <- get
        let (x, gen') = random gen
        put gen'
        return x
    
    这是我的代码,我只是在RandState.hs中编写的,因为我不知道如何导入它(帮助导入也很好,尽管这不是我最关心的):

    我想问题在于迭代获取一个值,将函数应用于该值,将函数应用于结果,依此类推,返回一个无限的结果列表。我正在处理一个iterate函数,它接受一个列表并返回一张卡片,因此结果不能传递给下一个迭代。解决这个问题的更好方法是什么(4)?我还担心我的removeCard函数有点笨拙,因为它只是将“已删除”的卡放在前面,我这样做是为了使shuffleDeck更容易编写。如有必要,解决此问题的更好方法是什么(3)

    谢谢,
    Jeff

    您应该停止在函数中运行random。您应该只在实际需要结果时使用
    runRandom
    (例如,打印结果,因为您不能在monad中执行此操作)。试图从monad中“逃脱”是一项徒劳的任务,您只会产生令人困惑且常常无法运行的代码。所有函数的最终输出都将在monad中,因此无论如何都不需要转义

    注意

    gen <- get
    let n = runRandom (randR(1, length (deck))) gen :: Int
    
    对:

    try = do
      a <- randomIO                                 :: IO Int
      let b = runRandom (randR (0,10)) (mkStdGen a) :: Int    -- 'execute' the randstate monad
      return $ a + b          
    
    try=do
    
    a我最好的客人是从f中取出“head$”,因为您希望迭代整个牌组(而不是第一张牌!)。它至少应该进行打字检查。编辑:是的,就是这样,你必须修正take参数,但你应该能够解决它。
    import
    应该导入东西:)感谢MdxBhmt,我从f中删除了head$,然后将head映射到迭代列表。不过,我无法让shuffleDeck显示其结果,显然是因为没有(Show(RandState[PlayingCard])的实例。有什么想法吗?还有jozefg,我昨晚已经试过导入了,但没有成功,但我现在又试了一次,成功了。也许你的评论是x因素,所以谢谢。@user2967411你不能打印RandState,因为它是一个函数,你必须
    runRandom
    并打印结果谢谢!这很有道理。现在我有一个关于掷骰子的问题。我回去后发现,这个问题要求我在实现中使用randR。所以我希望我能写一个更新的答案,并附上回复。
    RandState.hs:88:31:
        Occurs check: cannot construct the infinite type: a0 = [a0]
        Expected type: [a0] -> [a0]
          Actual type: [a0] -> a0
        In the first argument of `iterate', namely `f'
        In the second argument of `take', namely `(iterate f deck)'
        In the second argument of `($)', namely `take 52 (iterate f deck)'
    
    gen <- get
    let n = runRandom (randR(1, length (deck))) gen :: Int
    
    n <- randR (1, length deck)
    
    shuffleR [] = return []   
    shuffleR xs = do      
      (y:ys) <- removeR xs  -- 1
      zs <- shuffleR ys     -- 2
      return (y:zs)         -- 3
    
    randSum :: (Num b, Random b) => State StdGen b
    randSum = do
      a <- randR (1,6) 
      b <- randR (1,6) 
      return $ a + b
    
    try = do
      a <- randomIO      :: IO Int
      b <- randR (0,10)  :: RandState Int
      return $ a + b     -- monads don't match!
    
    try = do
      a <- randomIO                                 :: IO Int
      let b = runRandom (randR (0,10)) (mkStdGen a) :: Int    -- 'execute' the randstate monad
      return $ a + b