Printing x randomIO values from a list of randomIO's - haskell

I have been given this snippet of code and am supposed to explain it's non termination and propose a possible fix.
randomW = do randomvalues <- sequence (repeat (randomIO :: IO Float))
print (take 10 randomvalues)
Condition for the fix is to keep generating an infinite list so we may use the take function.
I think the problem stems from the not-so-lazy nature of the sequence function, which tries to reach the end of the list generated by repeat (randomIO :: IO Float), leading to non termination.
I'm also not sure about whether the repeat function is possible on randomIO.
test = do random <- repeat (randomIO :: IO Float)
print random
Which yields a type error. Print can't seem to be able to handle an IO Float, which seems to suggest that you can use repeat on type IO Float.

So:
repeat :: a -> [a]
randomIO :: Random a => IO a
sequence :: Monad m => [m a] -> m [a]
=>
repeat (randomIO :: IO Float) :: [IO Float]
So when you do:
random <- repeat (randomIO :: IO Float)
You're actually exploiting the list monad here, so random has type IO Float. Since you're in the list monad, your last statement needs to have type [a], but it has type IO () since it's a call to print, hence the type error.
The whole point of sequence is to transform this [IO a] into an IO [a] that you can perform to obtain a list of random values, and hopefully print this list. Now, when you perform an IO like this, it needs to be performed all at once, unless using unsafeInterleaveIO, which is not recommended in this case. So it tries to get that infinite list... and hangs (it might stack overflow at some point, I'm not sure).
To get an infinite list of random values, you don't need all this, just to obtain a random seed, and compute random values purely from the seed.
You should be able to construct an infinite list of random values using these functions:
randomIO :: Random a => IO a -- to provide an IO Int
mkStdGen :: Int -> StdGen -- to obtain a random generator from that Int
randoms :: RandomGen g => g -> [a] -- to generate the infinite list
Notice that the last two functions are pure. Reading this thread might give you some more ideas.
EDIT:
Example of how you should use mkStdGen:
randomList :: Random a => IO [a]
randomList = do seed <- randomIO
let gen = mkStdGen seed
return (randoms gen)
I can't test it right now but this should work. You probably want to adapt this to your use case though.
For your other question:
map :: (a -> b) -> [a] -> [b]
print :: Show a => a -> IO ()
=>
map print :: Show a => [a] -> [IO ()]
This probably isn't what you want, right?
If you just want to print a list, no need for map, print can handle lists.

The reason why your first code does not work, is that you're trying to sequence an infinite number of IO actions. Since this uses strict IO, the program is not allowed to continue before all the actions have been performed, which will take forever.
A simple solution is to take the number of actions you need before sequencing them, for example:
randomW = do values <- sequence (take 10 $ repeat (randomIO :: IO Float))
print values
This can be written more succinctly using replicateM from Control.Monad:
randomW = do values <- replicateM 10 (randomIO :: IO Float)
print values
Or, you can use randoms to make an infinite list of random numbers based on a single random seed (similar to Ptival's answer):
randomW = do gen <- newStdGen
let randomValues = randoms gen :: [Float]
print (take 10 randomValues)
Here, we only use a single IO action and the infinite list is generated lazily based on that, so there is no infinite number of side effects to run.

Related

Haskell: Chaining State Monad

If I have a function that shuffles a "deck of cards", how do I use the State Monad to iterate through a defined set number of shuffles and then return a result?
For example I have the following function that will do 1 shuffle of the deck then return a specific card:
step :: State [String] String
step = do
modify shuffle
deck <- get
pure $ bestCard deck
What I would like to be able to do is iterate through the state changes 5 times before I return the value.
What I have tried is this:
steps :: Int -> State [String] String
steps n = case n of
0 -> do
deck <- get
pure $ bestCard deck
_ -> do
modify shuffle
steps (n - 1)
but that looks far from being the correct way of doing it, even though it works.
NB. I am aware this can be done without using State Monad but I am trying to use this example to learn how to use State.
edit:
Thanks to #Koterpillar, I can use replicateM to get what I want.
evalState (replicateM n $ modify shuffle >> get >>= pure . bestCard)
The most succinct way to do it is replicateM_, which repeats a monadic action a specified number of times and discards the result:
replicateM_ 5 $ modify shuffle
Because State is a monad, you only have to care about repeating an action, not specifically working with State. I found the above function by searching Hoogle for the signature of the function I wanted:
Monad m => Int -> m a -> m ()
Note that the result doesn't even require a monad, just an applicative:
replicateM_ :: Applicative m => Int -> m a -> m ()

Using a random number to encrypt a message

I'm currently trying to encrypt a message (String) with the help of a random generated number in Haskell. The idea is to get the message, generate a random String of numbers with the same length (or more and then to take the length I need).
Then i want to perform some actions based on the ASCII representation and then return the encrypted String.
Unfortunately I'm not very versed with monads in Haskell, so it might be a very simple problem to solve, which I can't comprehend yet.
generateMyKey string = newStdGen >>= \x -> print $ concatMap show $ map abs $ rs x
where rs x = randomlist (length string) x
randomlist :: Int -> StdGen -> [Int]
randomlist n = take n . unfoldr (Just . random)
So the problem is I get an IO() out of getMyKey, but I want to have a String, or atleast a IO(String) to perform the encrypting mechanism.
Right now I'm getting a big list of positive (hence the abs + map) random numbers, but I can't access them.
There are two basic ways to go about this (and one more complicated but easier). If you're just using System.Random, you can generate random numbers in two ways, either by accepting a StdGen and staying pure, or using the OS's random generator and staying in IO. At some point, you'll have to make a call to the OS's random functionality to get a seed or value, but this can happen in main far away from your actual code.
To keep your functions pure, you'll need to pass around a StdGen and use the functions
random :: Random a => StdGen -> (a, StdGen)
randoms :: Random a => StdGen -> [a]
(Note: I've substituted RandomGen g => g for StdGen, there's no need to write a custom RandomGen instance for your case)
You can then write your function generateMyKey as
randomList :: Int -> StdGen -> [Int]
randomList n = take n . randoms
generateMyKey :: String -> StdGen -> String
generateMyKey text g
= concatMap show
$ map abs
$ randomList (length text) g
And this entirely avoids having to live in IO. Be wary, though, if you re-use the same g, you'll generate the same random list each time. We can avoid this by using IO and its related functions
randomList :: Int -> IO [Int]
randomList 0 = return []
randomList n = do
first <- randomIO
rest <- randomList (n - 1) -- Recursively generate the rest
return $ first : rest
generateMyKey :: String -> IO String
generateMyKey text = do
key <- randomList (length text)
return $ concatMap show $ map abs $ key
This will come with a performance hit, and now we've lost the ability to generate the same key repeatedly, making it difficult to test our functions reliably! How can we reconcile these two approaches?
Enter the package MonadRandom. This package provides a monad (and monad transformer, but you don't need to worry about that right now) that lets you abstract away how you generate random numbers so that you can choose how you want to run your code in different circumstances. If you want IO, you can use IO. If you want to supply a seed, you can supply a seed. It's very handy. You can install it with cabal install MonadRandom and use it as
import Control.Monad.Random
randomList :: Int -> Rand StdGen [Int]
randomList n = fmap (take n) getRandoms
generateMyKey :: String -> Rand StdGen String
generateMyKey text = do
key <- randomList (length text)
return $ concatMap show $ map abs $ key
Our generateMyKey code is even the same as the IO version other than the type signature!
Now to run it.
main :: IO ()
main = do
-- Entirely impure, have it automatically grab a StdGen from IO for us
ioVersion <- evalRandIO $ generateMyKey "password"
-- Make a StdGen that stays the same every time we run the program, useful for testing
let pureStdGen = mkStdGen 12345
pureVersion = evalRand (generateMyKey "password") pureStdGen
-- Get a StdGen from the system, but still evaluate it purely
ioStdGen <- getStdGen
let pureVersion2 = evalRand (generateMyKey "password") ioStdGen
-- Print out all three versions
putStrLn ioVersion
putStrLn pureVersion
putStrLn pureVersion2
There are a number of solutions to this problem, but at first glance it might seem that you need to have your entire program operate in the IO monad, but you don't! The entry (/exit) point of your program is the only place that needs to see IO -- you can factor out any transformations on your random list into pure functions, i.e:
import Data.List
import System.Random
generateMyKey :: String -> IO String
generateMyKey string = do
x <- newStdGen
let rs = randomlist (length string)
return $ concatMap show $ map abs $ rs x
randomlist :: Int -> StdGen -> [Int]
randomlist n = take n . unfoldr (Just . random)
change :: String -> String
change = reverse -- for example
main :: IO ()
main = do
key <- generateMyKey "what"
putStrLn $ change key
generateMyKey is identical to what you had before, except that it's written in do notation now and is returning the string instead of just printing it. This allows us to "pull out" a random key from inside the IO monad and transform it with regular pure functions, like change, for example. This allows you to reason about the pure functions as normal, while still pulling in your values from IO.

After reading a file I have IO [Char], but I need [IO Char]

I have a file number.txt which contains a large number and I read it into an IO String like this:
readNumber = readFile "number.txt" >>= return
In another function I want to create a list of Ints, one Int for each digit…
Lets assume the content of number.txt is:
1234567890
Then I want my function to return [1,2,3,4,5,6,7,8,9,0].
I tried severall versions with map, mapM(_), liftM, and, and, and, but I got several error messages everytime, which I was able to reduce to
Couldn't match expected type `[m0 Char]'
with actual type `IO String'
The last version I have on disk is the following:
module Main where
import Control.Monad
import Data.Char (digitToInt)
main = intify >>= putStrLn . show
readNumber = readFile "number.txt" >>= return
intify = mapM (liftM digitToInt) readNumber
So, as far as I understand the error, I need some function that takes IO [a] and returns [IO a], but I was not able to find such thing with hoogle… Only the other way round seemes to exist
In addition to the other great answers here, it's nice to talk about how to read [IO Char] versus IO [Char]. In particular, you'd call [IO Char] "an (immediate) list of (deferred) IO actions which produce Chars" and IO [Char] "a (deferred) IO action producing a list of Chars".
The important part is the location of "deferred" above---the major difference between a type IO a and a type a is that the former is best thought of as a set of instructions to be executed at runtime which eventually produce an a... while the latter is just that very a.
This phase distinction is key to understanding how IO values work. It's also worth noting that it can be very fluid within a program---functions like fmap or (>>=) allow us to peek behind the phase distinction. As an example, consider the following function
foo :: IO Int -- <-- our final result is an `IO` action
foo = fmap f getChar where -- <-- up here getChar is an `IO Char`, not a real one
f :: Char -> Int
f = Data.Char.ord -- <-- inside here we have a "real" `Char`
Here we build a deferred action (foo) by modifying a deferred action (getChar) by using a function which views a world that only comes into existence after our deferred IO action has run.
So let's tie this knot and get back to the question at hand. Why can't you turn an IO [Char] into an [IO Char] (in any meaningful way)? Well, if you're looking at a piece of code which has access to IO [Char] then the first thing you're going to want to do is sneak inside of that IO action
floob = do chars <- (getChars :: IO [Char])
...
where in the part left as ... we have access to chars :: [Char] because we've "stepped into" the IO action getChars. This means that by this point we've must have already run whatever runtime actions are required to generate that list of characters. We've let the cat out of the monad and we can't get it back in (in any meaningful way) since we can't go back and "unread" each individual character.
(Note: I keep saying "in any meaningful way" because we absolutely can put cats back into monads using return, but this won't let us go back in time and have never let them out in the first place. That ship has sailed.)
So how do we get a type [IO Char]? Well, we have to know (without running any IO) what kind of IO operations we'd like to do. For instance, we could write the following
replicate 10 getChar :: [IO Char]
and immediately do something like
take 5 (replicate 10 getChar)
without ever running an IO action---our list structure is immediately available and not deferred until the runtime has a chance to get to it. But note that we must know exactly the structure of the IO actions we'd like to perform in order to create a type [IO Char]. That said, we could use yet another level of IO to peek at the real world in order to determine the parameters of our action
do len <- (figureOutLengthOfReadWithoutActuallyReading :: IO Int)
return $ replicate len getChar
and this fragment has type IO [IO Char]. To run it we have to step through IO twice, we have to let the runtime perform two IO actions, first to determine the length and then second to actually act on our list of IO Char actions.
sequence :: [IO a] -> IO [a]
The above function, sequence, is a common way to execute some structure containing a, well, sequence of IO actions. We can use that to do our two-phase read
twoPhase :: IO [Char]
twoPhase = do len <- (figureOutLengthOfReadWithoutActuallyReading :: IO Int)
putStrLn ("About to read " ++ show len ++ " characters")
sequence (replicate len getChar)
>>> twoPhase
Determining length of read
About to read 22 characters
let me write 22 charac"let me write 22 charac"
You got some things mixed up:
readNumber = readFile "number.txt" >>= return
the return is unecessary, just leave it out.
Here is a working version:
module Main where
import Data.Char (digitToInt)
main :: IO ()
main = intify >>= print
readNumber :: IO String
readNumber = readFile "number.txt"
intify :: IO [Int]
intify = fmap (map digitToInt) readNumber
Such a function can't exists, because you would be able to evaluate the length of the list without ever invoking any IO.
What is possible is this:
imbue' :: IO [a] -> IO [IO a]
imbue' = fmap $ map return
Which of course generalises to
imbue :: (Functor f, Monad m) => m (f a) -> m (f (m a))
imbue = liftM $ fmap return
You can then do, say,
quun :: IO [Char]
bar :: [IO Char] -> IO Y
main = do
actsList <- imbue quun
y <- bar actsLists
...
Only, the whole thing about using [IO Char] is pointless: it's completely equivalent to the much more straightforward way of working only with lists of "pure values", only using the IO monad "outside"; how to do that is shown in Markus's answer.
Do you really need many different helper functions? Because you may write just
main = do
file <- readFile "number.txt"
let digits = map digitToInt file
print digits
or, if you really need to separate them, try to minimize the amount of IO signatures:
readNumber = readFile "number.txt" --Will be IO String
intify = map digitToInt --Will be String -> [Int], not IO
main = readNumber >>= print . intify

Haskell monad: IO [Double] to [IO Double]

Consider the following code that is supposed to print out random numbers:
import System.Random.Mersenne
main =
do g <- (newMTGen Nothing)
xs <- (randoms g) :: IO [Double]
mapM_ print xs
When run, I get a segmentation fault error. That is unsurprising, since the function 'randoms' produces an infinite list. Suppose I wanted to print out only the first ten values of xs. How could I do that? xs has type IO [Double], and I think I want a variable of type [IO Double]. What operators exist to convert between the two.
If you get a segmentation fault error, and you didn't use the FFI or any functions with unsafe in their name, that's not unsurprising, in any situation! It means there's a bug with either GHC, or a library you're using is doing something unsafe.
Printing out an infinite list of Doubles with mapM_ print is perfectly fine; the list will be processed incrementally and the program should run with constant memory usage. I suspect there is a bug in the System.Random.Mersenne module you're using, or a bug the C library it's based on, or a problem with your computer (such as faulty RAM).1 Note that newMTGen comes with this warning:
Due to the current SFMT library being vastly impure, currently only a single generator is allowed per-program. Attempts to reinitialise it will fail.
You might be better off using the provided global MTGen instead.
That said, you can't convert IO [Double] into [IO Double] in that way; there's no way to know how long the resulting list would be without executing the IO action, which is impossible, since you have a pure result (albeit one that happens to contain IO actions). For infinite lists, you could write:
desequence :: IO [a] -> [IO a]
desequence = desequence' 0
where
desequence n m = fmap (!! n) m : desequence (n+1) m
But every time you execute an action in this list, the IO [a] action would be executed again; it'd just discard the rest of the list.
The reason randoms can work and return an infinite list of random numbers is because it uses lazy IO with unsafeInterleaveIO. (Note that, despite the "unsafe" in the name, this one can't cause segfaults, so something else is afoot.)
1 Other, less likely possibilities include a miscompilation of the C library, or a bug in GHC.
Suppose I wanted to print out only the first ten values of xs. How could I do that?
Just use take:
main =
do g <- (newMTGen Nothing)
xs <- (randoms g) :: IO [Double]
mapM_ print $ take 10 xs
You wrote
xs has type IO [Double]
But actually, randoms g has type IO [Double], but thanks to the do notation, xs has type [Double], you can just apply take 10 to it.
You could also skip the binding using liftM:
main =
do g <- newMTGen Nothing
ys <- liftM (take 10) $ randoms g :: IO [Double]
mapM_ print ys

Is mapM in Haskell strict? Why does this program get a stack overflow?

The following program terminates correctly:
import System.Random
randomList = mapM (\_->getStdRandom (randomR (0, 50000::Int))) [0..5000]
main = do
randomInts <- randomList
print $ take 5 randomInts
Running:
$ runhaskell test.hs
[26156,7258,29057,40002,26339]
However, feeding it with an infinite list, the program never terminates, and when compiled, eventually gives a stack overflow error!
import System.Random
randomList = mapM (\_->getStdRandom (randomR (0, 50000::Int))) [0..]
main = do
randomInts <- randomList
print $ take 5 randomInts
Running,
$ ./test
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.
I expected the program to lazily evaluate getStdRandom each time I pick an item off the list, finishing after doing so 5 times. Why is it trying to evaluate the whole list?
Thanks.
Is there a better way to get an infinite list of random numbers? I want to pass this list into a pure function.
EDIT: Some more reading revealed that the function
randomList r = do g <- getStdGen
return $ randomRs r g
is what I was looking for.
EDIT2: after reading camccann's answer, I realized that getStdGen is getting a new seed on every call. Instead, better to use this function as a simple one-shot random list generator:
import System.Random
randomList :: Random a => a -> a -> IO [a]
randomList r g = do s <- newStdGen
return $ randomRs (r,g) s
main = do r <- randomList 0 (50::Int)
print $ take 5 r
But I still don't understand why my mapM call did not terminate. Evidently not related to random numbers, but something to do with mapM maybe.
For example, I found that the following also does not terminate:
randomList = mapM (\_->return 0) [0..]
main = do
randomInts <- randomList
print $ take 50000 randomInts
What gives? By the way, IMHO, the above randomInts function should be in System.Random. It's extremely convenient to be able to very simply generate a random list in the IO monad and pass it into a pure function when needed, I don't see why this should not be in the standard library.
Random numbers in general are not strict, but monadic binding is--the problem here is that mapM has to sequence the entire list. Consider its type signature, (a -> m b) -> [a] -> m [b]; as this implies, what it does is first map the list of type [a] into a list of type [m b], then sequence that list to get a result of type m [b]. So, when you bind the result of applying mapM, e.g. by putting it on the right-hand side of <-, what this means is "map this function over the list, then execute each monadic action, and combine the results back into a single list". If the list is infinite, this of course won't terminate.
If you simply want a stream of random numbers, you need to generate the list without using a monad for each number. I'm not entirely sure why you've used the design you have, but the basic idea is this: Given a seed value, use a pseudo-random number generator to produce a pair of 1) a random number 2) a new seed, then repeat with the new seed. Any given seed will of course provide the same sequence each time. So, you can use the function getStdGen, which will provide a fresh seed in the IO monad; you can then use that seed to create an infinite sequence in completely pure code.
In fact, System.Random provides functions for precisely that purpose, randoms or randomRs instead of random and randomR.
If for some reason you want to do it yourself, what you want is essentially an unfold. The function unfoldr from Data.List has the type signature (b -> Maybe (a, b)) -> b -> [a], which is fairly self-explanatory: Given a value of type b, it applies the function to get either something of type a and a new generator value of type b, or Nothing to indicate the end of the sequence.
You want an infinite list, so will never need to return Nothing. Thus, partially applying randomR to the desired range and composing it with Just gives this:
Just . randomR (0, 50000::Int) :: (RandomGen a) => a -> Maybe (Int, a)
Feeding that into unfoldr gives this:
unfoldr (Just . randomR (0, 50000::Int)) :: (RandomGen a) => a -> [Int]
...which does exactly as it claims: Given an instance of RandomGen, it will produce an infinite (and lazy) list of random numbers generated from that seed.
I would do something more like this, letting randomRs do the work with an initial RandomGen:
#! /usr/bin/env runhaskell
import Control.Monad
import System.Random
randomList :: RandomGen g => g -> [Int]
randomList = randomRs (0, 50000)
main :: IO ()
main = do
randomInts <- liftM randomList newStdGen
print $ take 5 randomInts
As for the laziness, what's happening here is that mapM is (sequence . map)
Its type is: mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
It's mapping the function, giving a [m b] and then needs to execute all those actions to make an m [b]. It's the sequence that'll never get through the infinite list.
This is explained better in the answers to a prior question: Is Haskell's mapM not lazy?

Resources