0

I'm trying to create a function for a silly IRC bot that will return a phrase where some of the letters are repeated a random number of times. The problem I'm having is that I can't find a way to use random numbers that ghc likes. It seems that even using this answer isn't being particularly helpful for getting my code to compile.

import System.Random


-- Write bad
baaad x y = "B" ++ (repeatA x) ++ "D " ++ (exclaim y)

-- StartHere    
randomBad :: String
randomBad = do
  x <- randomRIO(5,10) :: IO Int
  y <- randomRIO(0,6) :: IO Int
  return $ baaad x y


repeatA :: Int -> String
repeatA x = rptChr "A" x

exclaim :: Int -> String
exclaim x = rptChr "!" x

rptChr :: String -> Int -> String
rptChr x y = take y (cycle x)

Even with the trick of using a do block and passing the IO Ints to the function that way, I'm still getting compile errors that it found an IO Int when expecting Int.

Community
  • 1
  • 1
cjm
  • 451
  • 4
  • 20
  • 1
    Since `randomBad` uses I/O actions, its type should be `IO String`, not `String`. Also, please make your code self-contained by adding the required imports. – jub0bs Mar 26 '16 at 06:26
  • @Jubobs It's now added. I believe `System.Random` is all I need for this example (the whole bot itself uses a bunch of other imports that are probably irrelevant to this question). – cjm Mar 26 '16 at 06:30

1 Answers1

2

randomBad is not in the IO monad.... It is type String, but you are defining it to be type IO String

Change this

randomBad :: String

to this

randomBad :: IO String

Then you should be able to use this in another IO action, like main:

main = do
  theString <- randomBad
  putStrLn theString
jamshidh
  • 12,002
  • 17
  • 31
  • My bot is based on the code in [example 4 of this tutorial](https://wiki.haskell.org/Roll_your_own_IRC_bot), and it looks like I may need to change a whole bunch of things in there (specifically, the `privmsg` function) to deal with `IO String`s. Is this true, or is there some other refactoring I can do to avoid changing a bunch of types? – cjm Mar 26 '16 at 06:49
  • I just glanced quickly, but it looks like everything is already in the IO monad in that tutorial, so you probably won't have to change much.... The trick is that you can only use one IO monad in another (and so on until main), so if you have some pure portion of the code, you will not be able to use any random generator in it. – jamshidh Mar 26 '16 at 07:30
  • 1
    Just a note on terminology; `randomBad` itself is not in the IO monad; it is just a function that returns a monadic value. Such functions must be used "in" the monad, since there is no other way to extract (for example) a `String` from an `IO String` value. – chepner Mar 26 '16 at 13:43
  • I found that making the `privmsg` function really doesn't like to take both an `IO String` and a normal string as input. Is there a way to let it do that, or will these need to be separate functions with identical functionality? – cjm Mar 29 '16 at 06:18
  • @cjm- sorry, I would need to see what you are doing to help with this.... Why don't you ask a new question? – jamshidh Mar 29 '16 at 23:10