2016-08-31 4 views
1

У меня есть ввод с клавиатуры, например unsafePerformIO $ entryGetText myTextEntry. Как сохранить это значение как «константа» (в данных типа:«Константы» в Haskell после запуска программы

data SimuInfo = Information { 
       massSaved:: Double 
       } deriving Show 

) после запуска программы. Единственный метод, который я знаю, чтобы «сохранить переменные» является:

valuea::Int 
valuea = 120 

Но этот метод просто работает, когда значение не определяется пользователем.

Заранее спасибо

+2

Что случилось с 'value = unsafePerformIO $ entryGetText myTextEntry'? (Помимо того факта, что 'unsafePerformIO' не должен зависеть от его среды.) – chepner

+0

Почему мы используем unsafePerformIO? –

+6

Вы пытаетесь ошибочно закодировать на теоретически чистом языке. Это будет тяжелая битва. – Carcigenicate

ответ

6

unsafePerformIO should be avoided at all costs, а его исполнение непредсказуемо.

Haskell - это чистый язык, и значения неизменны, поэтому вы не сможете «сохранить» значение, которое будет отображаться как мутированное в другом месте.

Вместо этого вам нужно будет прочитать значение и передать его по мере необходимости.

main = do 
    putStrLn "Enter the default massSaved value" 
    val <- getLine 
    doThingsWithDefaultSimuInfo (Information (read val :: Double)) 

doThingsWithDefaultSimuInfo :: SimuInfo -> IO() 
doThingsWithDefaultSimuInfo si = do 
    ... 

(Есть более чистые и более идиоматические способы сделать это с помощью читателей, но я пытаюсь сохранить этот ответ, направленный на начинающем уровне)

+3

С тех пор, как в ответах было сказано дважды, я хотел бы упомянуть, что передача аргументов функции - это совершенно чистый и идиоматический способ сделать это (IMHO 'Reader' редко тянет свой вес как абстракция) – jberryman

+1

Вам не нужно ':: Double' на' read' здесь. Поскольку его результат передается конструктору 'Information', компилятор знает, что результат должен быть« Double ». – amalloy

0

Значения, которые вводятся с пользователя, не действительно постоянные. Я думаю, что обычный способ обработки такого ввода конфигурации - с помощью устройства Monad.

import Control.Monad.Reader 

-- type of our context, one double value. 
-- This is not really necessary, you could just use Double everywhere 
-- I use C. 
newtype C = C Double 
    deriving (Show, Eq) 

main :: IO() 
main = do 
    -- Read a double from the user. 
    c <- getLine >>= return . read :: IO Double 
    -- Run the computation, given a context/configuration with 
    -- the user input. 
    print $ runReader foo (C c) 

-- Computation dependent on our context. 
foo :: Reader C Double 
foo = do 
    C x <- ask -- Get the value of our context. 
    return $ x + 10 -- and use it