2014-09-13 62 views
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 

最後一行是發生錯誤的位置。 >>=預計爲IO String,但wordData.RVar.RVar String。 (這個變量叫'單詞',因爲每行應該是一個單詞。)

我已經閱讀了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 } 

最後,我知道有更有效的方式來接從文件中隨機線。我只是爲了最低限度的工作。我也是哈斯克爾的初學者,可能有一些基本的誤解,特別是關於IO和單子。

+1

你必須使用'runRVarT'來運行'選擇詞',它需要一個種子參數。由於[RVar'與'IO'不是單一的](http://stackoverflow.com/問題/ 25560448/composing-monadic-functions-with/25560521) – bheklilr 2014-09-13 20:18:45

回答

9

您可以使用

import Data.Random 

,然後修改主

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

這工作,因爲當您導入Data.Random它包含MonadRandom一個實例IO,讓您samplerunRVar一個方便的包裝使用從IO monad獲得的發生器。

+4

'putStrLn = <<(sample。choice。lines)= << readFile「wordlist.txt」'如果你喜歡pointfree golf :) – 2014-09-13 21:07:49