{"id":7083,"date":"2020-03-11T20:31:57","date_gmt":"2020-03-11T19:31:57","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=7083"},"modified":"2020-03-16T20:33:44","modified_gmt":"2020-03-16T19:33:44","slug":"i1m2019-aleatoriedad-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2019-aleatoriedad-en-haskell\/","title":{"rendered":"I1M2019: Aleatoriedad en Haskell"},"content":{"rendered":"<p>En la primera parte de la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-19\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> se ha estudiado como trabajar con la aleatoriedad en Haskell.<\/p>\n<p>El material utilizado ha sido el siguiente<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\nimport System.Random\n\n-- Las funciones mkStdGen y random:\n--    \u03bb> random (mkStdGen 100)\n--    (-3633736515773289454,693699796 2103410263)\n--    \u03bb> :type mkStdGen\n--    mkStdGen :: Int -> StdGen\n--    \u03bb> :type random\n--    random :: (Random a, RandomGen g) => g -> (a, g)\n--    \u03bb> random (mkStdGen 100)\n--    (-3633736515773289454,693699796 2103410263)\n--    \u03bb> random (mkStdGen 200)\n--    (-7150216019525618111,41011827 2103410263)\n--    \u03bb> random (mkStdGen 100)\n--    (-3633736515773289454,693699796 2103410263)\n--    \u03bb> random (mkStdGen 200)\n--    (-7150216019525618111,41011827 2103410263)\n--    \u03bb> random (mkStdGen 100) :: (Float,StdGen)\n--    (0.6512469,651872571 1655838864)\n--    \u03bb> random (mkStdGen 100) :: (Bool,StdGen)\n--    (True,4041414 40692)\n\n-- (tresMonedas g) genera una terna de booleanos (donde se interpreta\n-- True como cara y False como cruz) con el generador g. Por ejemplo,\n--    \u03bb> tresMonedas (mkStdGen 100)\n--    (True,False,False)\n--    \u03bb> tresMonedas (mkStdGen 100)\n--    (True,False,False)\n--    \u03bb> tresMonedas (mkStdGen 200)\n--    (True,False,True)\ntresMonedas :: StdGen -> (Bool, Bool, Bool)\ntresMonedas g = (x1,x2,x3)\n  where (x1,g1) = random g\n        (x2,g2) = random g1\n        (x3,_)  = random g2\n\n-- La funci\u00f3n randoms para generar listas aleatorias infinitas.  \n--    \u03bb> :t randoms\n--    randoms :: (Random a, RandomGen g) => g -> [a]\n--    \u03bb> take 2 $ randoms (mkStdGen 11) :: [Int]\n--    [5260538044923710387,4361398698747678847]\n--    \u03bb> take 2 $ randoms (mkStdGen 12) :: [Int]\n--    [-539234551526347469,-8970766343904053269]\n--    \u03bb> take 5 $ randoms (mkStdGen 12) :: [Bool]\n--    [True,False,True,False,False]\n\n-- Definici\u00f3n de randoms a partir de random. Por ejemplo, \n--    \u03bb> take 5 $ randoms' (mkStdGen 12) :: [Bool]\n--    [True,False,True,False,False]\nrandoms' :: (RandomGen g, Random a) => g -> [a]\nrandoms' g = x : randoms' g'\n  where (x, g') = random g\n\n-- (finitaAleatoria n g) es una lista de n elementos aleatorios a partir\n-- del generador n. Por ejemlo,\n--    \u03bb> finitaAleatoria 5 (mkStdGen 12) :: ([Bool],StdGen)\n--    ([True,False,True,False,False],929313902 652912057)\n--    \u03bb> finitaAleatoria 5 (mkStdGen 14) :: ([Bool],StdGen)\n--    ([True,False,False,True,True],246330055 652912057)\n--    \u03bb> finitaAleatoria 5 (mkStdGen 14) :: ([Bool],StdGen)\n--    ([True,False,False,True,True],246330055 652912057)\nfinitaAleatoria :: (RandomGen g, Random a, Num n, Eq n) => n -> g -> ([a], g)\nfinitaAleatoria 0 g = ([], g)\nfinitaAleatoria n g = (x:xs, g2)\n  where (x, g1)  = random g\n        (xs, g2) = finitaAleatoria (n-1) g1\n\n-- La funci\u00f3n randomR genera un elemento aleatorio en un rango.\n--    \u03bb> :type randomR\n--    randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)\n--    \u03bb> randomR (1,6) (mkStdGen 359353)\n--    (6,1494289578 40692)\n--    \u03bb> randomR (1,6) (mkStdGen 3593535)\n--    (6,2057834346 40692)\n\n-- La funci\u00f3n randomRs genera una lista infinitas de elementos\n-- aleatorios en un rango. \n--    \u03bb> :type randomRs\n--    randomRs :: (Random a, RandomGen g) => (a, a) -> g -> [a]\n--    \u03bb> take 10 $ randomRs ('a','z') (mkStdGen 3) :: [Char]\n--    \"xnuhlfwywq\"\n\n-- cadenaAleatoria genera una cadena aleatoria (a partir del generador\n-- est\u00e1ndard). Por ejemplo,  \n--    \u03bb> cadenaAleatoria\n--    \"tuxtznpeydhmtbekqbcz\"\n--    \u03bb> cadenaAleatoria\n--    \"tuxtznpeydhmtbekqbcz\"\ncadenaAleatoria :: IO String\ncadenaAleatoria = do\n  gen <- getStdGen\n  return (take 20 (randomRs ('a','z') gen))\n\n-- cadenaAleatoria genera una cadena aleatoria (a partir de un nuevo generador\n-- cada vez). Por ejemplo,  \n--    \u03bb> cadenaAleatoria2\n--    \"rlrzmlrpyfyocqfxctax\"\n--    \u03bb> cadenaAleatoria2\n--    \"ggcwqotrgggzqegochdf\"\ncadenaAleatoria2 :: IO String\ncadenaAleatoria2 = do\n  gen <- newStdGen\n  return (take 20 (randomRs ('a','z') gen))\n\n-- (pares n) es una lista de n cadenas de cadenas de dos letras min\u00fasculas.\n-- Por ejemplo,\n--    \u03bb> pares 3\n--    [\"om\",\"km\",\"bo\"]\n--    \u03bb> pares 3\n--    [\"ww\",\"zh\",\"lw\"]\npares :: Int -> IO [String]\npares n = do\n  gen <- newStdGen\n  let xs = randomRs ('a','z') gen\n      (as, ys) = splitAt n xs\n      (bs, _)  = splitAt n ys\n  return [[x,y] | (x,y) <- zip as bs]\n\n-- Las funciones randomRIO y randomIO\n--    \u03bb> :type randomRIO\n--    randomRIO :: Random a => (a, a) -> IO a\n--    \u03bb> randomRIO ('a', 'z')\n--    'r'\n--    \u03bb> randomRIO ('a', 'z')\n--    'h'\n--    \n--    \u03bb> :type randomIO\n--    randomIO :: Random a => IO a\n--    \u03bb> randomIO \n--    2463055754098132968\n--    \u03bb> randomIO :: IO Bool\n--    False\n\n-- tresMonedas2 genera una terna de booleanos (donde se interpreta\n-- True como cara y False como cruz). Por ejemplo,\n--    \u03bb> tresMonedas2\n--    (True,False,True)\n--    \u03bb> tresMonedas2\n--    (False,False,True)\ntresMonedas2 :: IO (Bool, Bool, Bool)\ntresMonedas2 = do\n  x <- randomIO\n  y <- randomIO\n  z <- randomIO\n  return (x, y, z)\n\n-- dosDados genera un par que simula la tirada de dos dados. Por ejemplo,\n--    \u03bb> dosDados\n--    (3,3)\n--    \u03bb> dosDados\n--    (2,5)\ndosDados :: IO (Int, Int)\ndosDados = do\n  x1 <- randomRIO (1, 6)\n  x2 <- randomRIO (1, 6)\n  return (x1, x2)\n\n-- (pares2 n) es una lista de n cadenas de cadenas de dos letras min\u00fasculas.\n-- Por ejemplo,\n--    \u03bb> pares2 3\n--    [\"kx\",\"om\",\"ka\"]\n--    \u03bb> pares2 3\n--    [\"sm\",\"fc\",\"fh\"]\npares2 :: Int -> IO [String]\npares2 0 = return []\npares2 n = do\n  x1 <- randomRIO ('a', 'z')\n  x2 <- randomRIO ('a', 'z')\n  xs <- pares2 (n-1)\n  return ([x1,x2] : xs)\n  \n-- Informaci\u00f3n de la clase Random\n--    \u03bb> :info Random\n--    class Random a where\n--      randomR :: RandomGen g => (a, a) -> g -> (a, g)\n--      random :: RandomGen g => g -> (a, g)\n--      randomRs :: RandomGen g => (a, a) -> g -> [a]\n--      randoms :: RandomGen g => g -> [a]\n--      randomRIO :: (a, a) -> IO a\n--      randomIO :: IO a\n--      {-# MINIMAL randomR, random #-}\n--             -- Defined in \u2018System.Random\u2019\n--    instance Random Word -- Defined in \u2018System.Random\u2019\n--    instance Random Integer -- Defined in \u2018System.Random\u2019\n--    instance Random Int -- Defined in \u2018System.Random\u2019\n--    instance Random Float -- Defined in \u2018System.Random\u2019\n--    instance Random Double -- Defined in \u2018System.Random\u2019\n--    instance Random Char -- Defined in \u2018System.Random\u2019\n--    instance Random Bool -- Defined in \u2018System.Random\u2019\n<\/pre>\n<p>y la secci\u00f3n <a href=\"http:\/\/aprendehaskell.es\/content\/EntradaSalida.html#aleatoriedad\">Aleatoriedad<\/a> del libro <a href=\"http:\/\/aprendehaskell.es\">\u00a1Aprende Haskell por el bien de todos!<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la primera parte de la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas se ha estudiado como trabajar con la aleatoriedad en Haskell. El material utilizado ha sido el siguiente<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[331],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7083"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=7083"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7083\/revisions"}],"predecessor-version":[{"id":7085,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7083\/revisions\/7085"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=7083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=7083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=7083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}