从Haskell中的文件中挑选一条随机行

doo*_*ree 4 haskell

我试图让Haskell从文件中选择一个随机行并打印出来.我的尝试如下:

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

最后一行是发生错误的地方. >>=期待一个IO String,但是wordData.RVar.RVar String.(该变量称为"word",因为每行应该是一个单词.)

我已经阅读了RVar的文档,但经过一些黑客攻击后,我看不出如何解决我的问题.有任何想法吗?

我在安装Haskell平台OS X 10.9时使用ghc 7.6.3.

完整的错误如下:

[ 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 }
Run Code Online (Sandbox Code Playgroud)

最后,我知道有更有效的方法从文件中选择一个随机行.我只是为了最低限度的工作.我也是一个Haskell初学者,可能有一些基本的误解,特别是关于IO和monads.

fel*_*lix 9

您可以使用

import Data.Random
Run Code Online (Sandbox Code Playgroud)

然后修改main

main = do
...
  let word = sample $ choice words
  putStrLn =<< word
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为当你导入Data.Random它时包含MonadRandomfor的一个实例,IO并为你sample提供一个方便的包装器,用于runRVar从IO monad获得的生成器.

  • `putStrLn = <<(样本.选择.行)= << readFile"wordlist.txt"`如果你喜欢无点高尔夫:) (4认同)