Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picking a random line from a file in Haskell

Tags:

haskell

I am trying to have Haskell pick a random line from a file and print it. My attempt is below:

import Data.Random.Extras (choice)
main :: IO ()
main = do
  filecontents <- readFile "wordlist.txt"
  let words = lines filecontents
  let word = choice $ words
  word >>= putStrLn

The last line is where the error occurs. >>= expects an IO String, but word is a Data.RVar.RVar String. (The variable is called `word' because each line should be one word.)

I have read the docs for RVar but after some hacking, I do not see how to solve my problem. Any ideas?

I am using ghc 7.6.3 from an installation of the Haskell Platform, OS X 10.9.

The complete error is below:

[ 01:46 PM (51) integral:thoth ~/Source/pwgen ] > ghc -o pwgen pwgen.hs
[1 of 1] Compiling Main             ( pwgen.hs, pwgen.o )

pwgen.hs:40:3:
    Couldn't match type `Data.RVar.RVarT
                           Data.Functor.Identity.Identity'
                  with `IO'
    Expected type: IO String
      Actual type: Data.RVar.RVar String
    In the first argument of `(>>=)', namely `word'
    In a stmt of a 'do' block: word >>= putStrLn
    In the expression:
      do { filecontents <- readFile "wordlist.txt";
           let words = lines filecontents;
           let word = choice $ words;
           word >>= putStrLn }

Finally, I am aware that there are more efficient ways to pick a random line from a file. I'm just going for the bare minimum that works. I am also very much a Haskell beginner and may have some fundamental misconceptions, especially regarding IO and monads.

like image 591
door_number_three Avatar asked Jan 09 '23 20:01

door_number_three


1 Answers

You can use

import Data.Random

and then modify main

main = do
...
  let word = sample $ choice words
  putStrLn =<< word

This works because when you import Data.Random it contains an instance of MonadRandom for IO and gives you sample as a convenient wrapper for runRVar with a generator obtained from the IO monad.

like image 89
felix Avatar answered Jan 19 '23 10:01

felix