我一直在尝试从序列中提取随机元素。我想要定义的函数如下:
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
有没有人知道如何解决这个问题,或者,建议采用一种有效的方法从序列中获取随机元素(无需替换)?
答案 0 :(得分: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
为您完成这项工作。