【问题标题】:Extracting Random Items from a Sequence从序列中提取随机项
【发布时间】:2012-12-31 02:17:58
【问题描述】:

我一直在尝试从序列中提取随机元素。我要定义的功能如下:

getRandomInts :: Seq Int -> PureMT -> ((Seq Int, Int), PureMT)
getRandomInts ints gen = sampleState (fromJust $ choiceExtractSeq ints) gen

这是我得到的错误:

Overlapping instances for Data.Random.Lift.Lift
      transformers-0.3.0.0:Data.Functor.Identity.Identity
      (StateT PureMT transformers-0.3.0.0:Data.Functor.Identity.Identity)
  arising from a use of `sampleState'
Matching instances:
  instance [incoherent] (Monad m, MonadTrans t) =>
                        Data.Random.Lift.Lift m (t m)
    -- Defined in `Data.Random.Lift'
  instance [incoherent] Monad m =>
                        Data.Random.Lift.Lift
                          transformers-0.3.0.0:Data.Functor.Identity.Identity m
    -- Defined in `Data.Random.Lift'
In the expression:
  sampleState (fromJust $ choiceExtractSeq ints) gen
In an equation for `getRandomInt':
    getRandomInt ints gen
      = sampleState (fromJust $ choiceExtractSeq ints) gen

有谁知道如何解决这个问题,或者,有没有人建议一种有效的方法来从序列中获取随机元素(无需替换)?

【问题讨论】:

    标签: haskell random sequence monads


    【解决方案1】:

    我对这个程序也有类似的问题:

    sampleState (uniform (1 :: Int) 100 :: RVar Int) (mkStdGen 1)
    

    这会导致几乎相同的错误消息。这里的问题是Data.Random.Lift 中有重叠的实例,但是没有最具体的实例,所以 ghc 拒绝了该程序(在user's guide 中有描述)。

    我解决此问题的方法是提供一个比其他实例更具体的实例,因此只需删除以下实例就可以让所有内容都能正常编译(我已包含完整的语言编译指示和导入):

    {-# LANGUAGE OverlappingInstances, 
                 IncoherentInstances, 
                 FlexibleInstances, 
                 MultiParamTypeClasses #-}
    
    import Data.Random
    import Data.Random.Distribution.Uniform
    import System.Random
    
    import Data.Random.Lift
    import Data.Functor.Identity
    import Control.Monad.Trans.Class as T
    
    main = print test
    
    test :: (Int, StdGen)
    test = sampleState (uniform (1 :: Int) 100 :: RVar Int) (mkStdGen 1)
    
    instance MonadTrans t => Lift Identity (t Identity) where
      lift = T.lift
    

    简而言之,尝试通过为Data.Random.Lift.Lift 编写更具体的实例来指导编译器。

    更新

    我已经为 random-fu 作者创建了一个pull request,并带有一个在库中修复此问题的补丁。在被接受之前,您可以从我的fork 中提取,并使用cabal install 为您完成这项工作。

    【讨论】:

    • 另一种选择是通过将sampleState 替换为(runState . sampleRVar) 来避免使用Lift(我很想完全淘汰它,它总是会导致这样的问题)。后一个函数在Data.RVar模块中,稍低级,不使用Lift
    猜你喜欢
    • 1970-01-01
    • 2014-06-20
    • 2016-01-17
    • 2013-01-13
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多