jeudi 1 octobre 2020

How to join two Haskell IO monads

The following (working) Haskell program outputs a random spell:

import System.Random

spells =
  [ "Abracadabra!"
  , "Hocus pocus!"
  , "Simsalabim!"
  ]

main :: IO()
main = do
  spell <- (spells !!) <$> randomRIO (0, length spells - 1)
  putStrLn spell

However, the variable spell is quite useless. It stores the random string selected from the list of spells, but is then immediately passed to the putStrLn function and is never used again. I tried to combine the two IO operations into a single line like this:

main = putStrLn <$> (spells !!) <$> randomRIO (0, length spells - 1)

But I got the following error:

    • Couldn't match type ‘IO ()’ with ‘()’
      Expected type: Int -> ()
        Actual type: Int -> IO ()
    • In the first argument of ‘(<$>)’, namely
        ‘putStrLn <$> (spells !!)’
      In the expression:
        putStrLn <$> (spells !!) <$> randomRIO (0, length spells - 1)
      In an equation for ‘main’:
          main
            = putStrLn <$> (spells !!) <$> randomRIO (0, length spells - 1)
    |
160 | main = putStrLn <$> (spells !!) <$> randomRIO (0, length spells - 1)
    |        ^^^^^^^^^^^^^^^^^^^^^^^^

Is there a way to combine the two IO operations into a single line? I looked at this similar question but I couldn't understand the answer.




Aucun commentaire:

Enregistrer un commentaire