una recorrer listas lista funcion definir crear haskell

haskell - recorrer - ¿Cómo elegir un elemento de lista aleatorio en una función pura?



listas en racket (3)

Parte de la definición de una función "pura" en Haskell es que es referencialmente transparente , es decir, intercambiable con el resultado de evaluarla. Esto implica que el resultado de evaluarlo debe ser el mismo cada vez. Ergo, la función que quieres no es posible, me temo. Para generar números aleatorios en Haskell, una función necesita hacer una de dos cosas:

Tome y devuelva un generador de números pseudoaleatorios, por ejemplo:

randomPick :: RNG -> [a] -> (a, RNG)

O use IO para acceder a la aleatoriedad del "mundo exterior":

randomPick :: [a] -> IO a

Ambos estilos son proporcionados por el módulo System.Random . Además, en el primer caso, se puede abstraer el PRNG usando la mónada de State , o quizás una mónada aleatoria de propósito especial .

Quiero hacer una función Haskell que pueda seleccionar un número aleatorio de una lista dada. Mi tipo de firma es:

randomPick :: [a] -> a

¿Que debería hacer?


Si desea utilizar generadores de números aleatorios en código puramente funcional pero no tiene que pasar explícitamente por el estado del generador, puede usar la mónada de estado (o transformador de mónada) y ocultar las tuberías. Las mónadas estatales todavía son referencialmente transparentes y es seguro y normal escapar de una mónada estatal. También puede usar la mónada ST si desea una verdadera caja de seguridad mutable que sea puramente funcional en el exterior.

Aquí hay algunos códigos útiles que escribí y uso a veces:

rand :: (Random a, RandomGen g, MonadState g m) => a -> a -> m a rand lo hi = do r <- get let (val, r'') = randomR (lo, hi) r put r'' return val


Lo que has descrito no se puede hacer en código funcional puro.

El código funcional puro implica que obtendrá la misma salida para la misma entrada, siempre. Como una función aleatorizada, por definición, le da salida diferente para la misma entrada, esto es imposible en el código funcional puro.

A menos que pase alrededor de un valor adicional como se explica en la respuesta de @camccann . Técnicamente, ni siquiera tiene que ser tan avanzado como un RNG, según tus necesidades. Podría pasar alrededor de un número entero, y multiplicarlo por 10 y restar 3 (o lo que sea), luego tome el módulo de eso para encontrar su índice. Entonces su función permanece pura, pero usted controla directamente la aleatoriedad.

Otra opción es usar RandomRIO para generar un número en un rango, que luego puede usar para seleccionar un índice de la lista. Esto requerirá que ingrese la mónada IO.