如何使用另一个do块中产生的值?

时间:2015-08-03 19:02:24

标签: haskell

我刚刚在Haskell上观看了一段视频,所以我尝试了一下它,但我无法理解这一点(简而言之,我想打印一个随机值):

import System.Random
import System.IO

randomNum = do
   gen <- newStdGen
   let ns = randoms gen :: [Int]
   let val = take 10 ns 
   print $ head val

writeToFile = do
    theFile <- openFile "test.txt" WriteMode
    let val = randomNum;
    hPutStrLn theFile ("Random number " ++ randomNum)
    hClose theFile

readFromFile = do 
    theFile2 <- openFile  "test.txt" ReadMode
    contents <- hGetContents theFile2
    putStr contents
    hClose theFile2

randomNum似乎运行正常但是当我尝试将它放在writeToFile上时会触发错误。我该怎么办?

提前致谢!

编辑:我在开头得到的错误是:

Prelude> :r
[1 of 1] Compiling Main             ( haskell.hs, interpreted )

haskell.hs:207:48:
    No instance for (Show (IO ())) arising from a use of `show'
    In the second argument of `(++)', namely `show randomNum'
    In the second argument of `hPutStrLn', namely
      `("Random number " ++ show randomNum)'
    In a stmt of a 'do' block:
      hPutStrLn theFile ("Random number " ++ show randomNum)
Failed, modules loaded: none.

2 个答案:

答案 0 :(得分:4)

看起来你需要的是

randomNum = do
   gen <- newStdGen
   return (head (randoms gen :: [Int]))

writeToFile = do
    theFile <- openFile "test.txt" WriteMode
    val <- randomNum
    hPutStrLn theFile ("Random number " ++ show val)
    hClose theFile

答案 1 :(得分:1)

您可以尝试这样做:

import System.Random
import System.IO

writeToFile = do
    gen <- newStdGen
    let ns = randoms gen :: [Int]
    let val = head ns;
    theFile <- openFile "test.txt" WriteMode
    hPutStrLn theFile ("Random number " ++ show val)
    hClose theFile

readFromFile = do 
    theFile2 <- openFile  "test.txt" ReadMode
    contents <- hGetContents theFile2
    putStr contents
    hClose theFile2

一个问题是do中的randomNum块没有返回值;相反,它执行了你告诉它要做的动作:打印一个随机数。作为替代方案,请参阅Louis Wasserman's answer以获取使randomNum实际返回值的方法。在这个答案的代码中,随机数生成刚刚移入writeToFile。

另请注意,我缩短了代码以获得一个随机值:ns已经是一个列表,因此您可以立即使用headtake 10是多余的。

最后,val是一个Int,它不能直接连接到字符串上。使用show val将其转换为可与"Random number "

连接的字符串