2015-08-03 2 views
0

Я просто смотрел видео на Haskell, так что я пытался играть немного с ним, но я не могу понять это (Короче говоря, я хочу, чтобы напечатать одну случайную величину):Как использовать значение, произведенное в другом блоке do?

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, он вызывает ошибку. Что я могу сделать?

Заранее благодарен!

EDIT: Я получаю ошибку в начале это:

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. 
+1

Какая ошибка вы получаете? –

+0

Прелюдия>: г [1 из 1] Сборка Основное (haskell.hs, интерпретируемый) haskell.hs: 207: 48: не могли соответствовать Ожидаемый тип '[Char]» с фактическим типом 'IO() Во втором аргументе '(++) ', а именно' randomNum' Во втором аргументе 'hPutStrLn ', а именно ' («Случайное число» ++ randomNum)' Ошибка, модули загружены: нет. – ffuentes

+0

Если вы хотите только одно значение, вы можете просто написать 'val <- randomIO :: IO Int', или' val <- randomRIO (1 :: Int, 10) ', чтобы получить его в определенном диапазоне (здесь, из От 1 до 10 включительно). –

ответ

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 

One проблема заключалась в том, что блок do в вашем randomNum не возвратил значение; скорее, он выполнил действие, которое вы ему сказали: напечатайте случайное число. В качестве альтернативы, см. Louis Wasserman's answer для того, чтобы сделать randomNum фактически возвращением значения. В коде этого ответа генерация случайных чисел была просто перемещена в writeToFile.

Также обратите внимание, что я сократил код, чтобы получить одно случайное значение: ns уже есть список, поэтому вы можете сразу же взять его head. take 10 был избыточным.

Наконец, val был Int, который не может быть объединен непосредственно на строку. Использование show val преобразует его в строку, которая может быть объединена с "Random number "

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 
+0

Я пробовал, и я получаю «Не могу совместить тип IO() с IO() -> Int – ffuentes

+0

... вы получаете что? –

+0

Попробуйте это, я думаю. –

Смежные вопросы