import Control.Monad
import Control.Monad.Random as MR
import Control.Monad.ST
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import qualified Data.Vector as V
import qualified Data.Vector.Generic as VG
import Data.Vector.Generic.Mutable as VGM
import qualified Data.Vector.Unboxed as VU
data Obj m = Obj
{ aNum :: Int
, vec :: m (VU.Vector Int)
}
instance Show (Obj m) where
show Obj{ aNum = a
, vec = v
} = show a ++ show v -- 'show v' not OK
main :: IO()
main = do
rVec <- evalRandIO (randVector 5) -- OK
obj <- evalRandIO (newObj 1 5) -- Not OK
print $ show rVec
print $ show obj
newObj :: (MonadRandom m) => Int -> Int -> Obj m
newObj aNum' vecLen = Obj aNum' $ randVector vecLen
randVector :: (MonadRandom m) => Int -> m (VU.Vector Int)
randVector len = randSample (VU.enumFromN 0 len) $ VG.length vec
-- Fisher-yates shuffle
randSample :: (MonadRandom m, (VG.Vector v a)) => v a -> Int -> m (v a)
randSample vec len = do
let getR i = do
r <- getRandomR (i, (VG.length vec)-1)
return (i, r)
swaps <- mapM getR [0..len-1]
let vec_rands = runST $ do
vec_mut <- VG.thaw vec
forM_ swaps $ \(i, j) -> do
VGM.swap vec_mut i j
vec_rands' <- VG.unsafeFreeze vec_mut
return vec_rands'
return $ VG.take len vec_rands
У меня возникли проблемы с созданием структур данных с монадами. В частности, структура данных содержит случайный вектор и некоторые другие поля, которые не являются случайными. Использование evalRandIO
работает, когда весь тип является монадой, но не тогда, когда только часть структуры данных является монадой.Структуры данных с монадами
У меня возникает ощущение, что я должен использовать fmap
или что-то в этом роде, но они дают разные ошибки. У меня также есть проблемы с преобразованием случайного вектора в строку, чтобы напечатать его на экране. Я не знаю разницы между Rand g
и MonadRandom m
, и какой из них я должен использовать. Последние, похоже, работают, но все примеры онлайн, похоже, используют Rand g
. Кроме того. Также оценивается общий обзор кода.
* Couldn't match type `Obj m1' with `RandT StdGen Data.Functor.Identity.Identity a0' Expected type: Rand StdGen a0 Actual type: Obj m1 * In the first argument of `evalRandIO', namely `(newObj 1 5)' In a stmt of a 'do' block: obj <- evalRandIO (newObj 1 5) In the expression: do { rVec <- evalRandIO (randVector 5); obj <- evalRandIO (newObj 1 5); print $ show rVec }
'm (Vector Int)' не является вектором или структурой данных. Почему у вас есть это 'm' там? – melpomene
Если я не получаю ошибки типа при вызове 'randVector' в' newObj' – tsorn
'newObj n vecLen = do {vec <- randVector vecLen; return (Obj n vec)} ' – melpomene