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
Ich habe Probleme beim Erstellen von Datenstrukturen mit Monaden. Insbesondere enthält die Datenstruktur einen Zufallsvektor und einige andere Felder, die nicht zufällig sind. Die Verwendung von evalRandIO
funktioniert, wenn der ganze Typ eine Monade ist, aber nicht, wenn nur ein Teil der Datenstruktur eine Monade ist. Ich habe das Gefühl, dass ich fmap
oder etwas ähnliches verwenden sollte, aber sie geben andere Fehler. Ich habe auch Probleme, einen zufälligen Vektor in eine Zeichenfolge zu konvertieren, um sie auf dem Bildschirm zu drucken. Ich bin mir nicht sicher über den Unterschied zwischen Rand g
und MonadRandom m
, und welche ich verwenden sollte. Letztere scheinen zu funktionieren, aber alle Online-Beispiele scheinen stattdessen Rand g
zu verwenden. Außerdem. Allgemeine Code-Überprüfung wird ebenfalls geschätzt.Datenstrukturen mit Monaden
* 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)' ist keine Vektor- oder Datenstruktur. Warum hast du das 'm' drin? – melpomene
Wenn ich nicht bekomme, bekomme ich Typ-Fehler beim Aufruf von 'randVector' in' newObj' – tsorn
'newObj n vecLen = do {vec <- randVector vecLen; return (Obj n vec)} ' – melpomene