I1M2019: Aleatoriedad en Haskell
En la primera parte de la clase de hoy de Informática de 1º del Grado en Matemáticas se ha estudiado como trabajar con la aleatoriedad en Haskell.
El material utilizado ha sido el siguiente
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
import System.Random -- Las funciones mkStdGen y random: -- λ> random (mkStdGen 100) -- (-3633736515773289454,693699796 2103410263) -- λ> :type mkStdGen -- mkStdGen :: Int -> StdGen -- λ> :type random -- random :: (Random a, RandomGen g) => g -> (a, g) -- λ> random (mkStdGen 100) -- (-3633736515773289454,693699796 2103410263) -- λ> random (mkStdGen 200) -- (-7150216019525618111,41011827 2103410263) -- λ> random (mkStdGen 100) -- (-3633736515773289454,693699796 2103410263) -- λ> random (mkStdGen 200) -- (-7150216019525618111,41011827 2103410263) -- λ> random (mkStdGen 100) :: (Float,StdGen) -- (0.6512469,651872571 1655838864) -- λ> random (mkStdGen 100) :: (Bool,StdGen) -- (True,4041414 40692) -- (tresMonedas g) genera una terna de booleanos (donde se interpreta -- True como cara y False como cruz) con el generador g. Por ejemplo, -- λ> tresMonedas (mkStdGen 100) -- (True,False,False) -- λ> tresMonedas (mkStdGen 100) -- (True,False,False) -- λ> tresMonedas (mkStdGen 200) -- (True,False,True) tresMonedas :: StdGen -> (Bool, Bool, Bool) tresMonedas g = (x1,x2,x3) where (x1,g1) = random g (x2,g2) = random g1 (x3,_) = random g2 -- La función randoms para generar listas aleatorias infinitas. -- λ> :t randoms -- randoms :: (Random a, RandomGen g) => g -> [a] -- λ> take 2 $ randoms (mkStdGen 11) :: [Int] -- [5260538044923710387,4361398698747678847] -- λ> take 2 $ randoms (mkStdGen 12) :: [Int] -- [-539234551526347469,-8970766343904053269] -- λ> take 5 $ randoms (mkStdGen 12) :: [Bool] -- [True,False,True,False,False] -- Definición de randoms a partir de random. Por ejemplo, -- λ> take 5 $ randoms' (mkStdGen 12) :: [Bool] -- [True,False,True,False,False] randoms' :: (RandomGen g, Random a) => g -> [a] randoms' g = x : randoms' g' where (x, g') = random g -- (finitaAleatoria n g) es una lista de n elementos aleatorios a partir -- del generador n. Por ejemlo, -- λ> finitaAleatoria 5 (mkStdGen 12) :: ([Bool],StdGen) -- ([True,False,True,False,False],929313902 652912057) -- λ> finitaAleatoria 5 (mkStdGen 14) :: ([Bool],StdGen) -- ([True,False,False,True,True],246330055 652912057) -- λ> finitaAleatoria 5 (mkStdGen 14) :: ([Bool],StdGen) -- ([True,False,False,True,True],246330055 652912057) finitaAleatoria :: (RandomGen g, Random a, Num n, Eq n) => n -> g -> ([a], g) finitaAleatoria 0 g = ([], g) finitaAleatoria n g = (x:xs, g2) where (x, g1) = random g (xs, g2) = finitaAleatoria (n-1) g1 -- La función randomR genera un elemento aleatorio en un rango. -- λ> :type randomR -- randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g) -- λ> randomR (1,6) (mkStdGen 359353) -- (6,1494289578 40692) -- λ> randomR (1,6) (mkStdGen 3593535) -- (6,2057834346 40692) -- La función randomRs genera una lista infinitas de elementos -- aleatorios en un rango. -- λ> :type randomRs -- randomRs :: (Random a, RandomGen g) => (a, a) -> g -> [a] -- λ> take 10 $ randomRs ('a','z') (mkStdGen 3) :: [Char] -- "xnuhlfwywq" -- cadenaAleatoria genera una cadena aleatoria (a partir del generador -- estándard). Por ejemplo, -- λ> cadenaAleatoria -- "tuxtznpeydhmtbekqbcz" -- λ> cadenaAleatoria -- "tuxtznpeydhmtbekqbcz" cadenaAleatoria :: IO String cadenaAleatoria = do gen <- getStdGen return (take 20 (randomRs ('a','z') gen)) -- cadenaAleatoria genera una cadena aleatoria (a partir de un nuevo generador -- cada vez). Por ejemplo, -- λ> cadenaAleatoria2 -- "rlrzmlrpyfyocqfxctax" -- λ> cadenaAleatoria2 -- "ggcwqotrgggzqegochdf" cadenaAleatoria2 :: IO String cadenaAleatoria2 = do gen <- newStdGen return (take 20 (randomRs ('a','z') gen)) -- (pares n) es una lista de n cadenas de cadenas de dos letras minúsculas. -- Por ejemplo, -- λ> pares 3 -- ["om","km","bo"] -- λ> pares 3 -- ["ww","zh","lw"] pares :: Int -> IO [String] pares n = do gen <- newStdGen let xs = randomRs ('a','z') gen (as, ys) = splitAt n xs (bs, _) = splitAt n ys return [[x,y] | (x,y) <- zip as bs] -- Las funciones randomRIO y randomIO -- λ> :type randomRIO -- randomRIO :: Random a => (a, a) -> IO a -- λ> randomRIO ('a', 'z') -- 'r' -- λ> randomRIO ('a', 'z') -- 'h' -- -- λ> :type randomIO -- randomIO :: Random a => IO a -- λ> randomIO -- 2463055754098132968 -- λ> randomIO :: IO Bool -- False -- tresMonedas2 genera una terna de booleanos (donde se interpreta -- True como cara y False como cruz). Por ejemplo, -- λ> tresMonedas2 -- (True,False,True) -- λ> tresMonedas2 -- (False,False,True) tresMonedas2 :: IO (Bool, Bool, Bool) tresMonedas2 = do x <- randomIO y <- randomIO z <- randomIO return (x, y, z) -- dosDados genera un par que simula la tirada de dos dados. Por ejemplo, -- λ> dosDados -- (3,3) -- λ> dosDados -- (2,5) dosDados :: IO (Int, Int) dosDados = do x1 <- randomRIO (1, 6) x2 <- randomRIO (1, 6) return (x1, x2) -- (pares2 n) es una lista de n cadenas de cadenas de dos letras minúsculas. -- Por ejemplo, -- λ> pares2 3 -- ["kx","om","ka"] -- λ> pares2 3 -- ["sm","fc","fh"] pares2 :: Int -> IO [String] pares2 0 = return [] pares2 n = do x1 <- randomRIO ('a', 'z') x2 <- randomRIO ('a', 'z') xs <- pares2 (n-1) return ([x1,x2] : xs) -- Información de la clase Random -- λ> :info Random -- class Random a where -- randomR :: RandomGen g => (a, a) -> g -> (a, g) -- random :: RandomGen g => g -> (a, g) -- randomRs :: RandomGen g => (a, a) -> g -> [a] -- randoms :: RandomGen g => g -> [a] -- randomRIO :: (a, a) -> IO a -- randomIO :: IO a -- {-# MINIMAL randomR, random #-} -- -- Defined in ‘System.Random’ -- instance Random Word -- Defined in ‘System.Random’ -- instance Random Integer -- Defined in ‘System.Random’ -- instance Random Int -- Defined in ‘System.Random’ -- instance Random Float -- Defined in ‘System.Random’ -- instance Random Double -- Defined in ‘System.Random’ -- instance Random Char -- Defined in ‘System.Random’ -- instance Random Bool -- Defined in ‘System.Random’ |
y la sección Aleatoriedad del libro ¡Aprende Haskell por el bien de todos!.