2016-08-31 7 views
1

unsafePerformIO $ entryGetText myTextEntryのようなキーボード入力があります。この値を「定数」のように保存するにはどうすればいいですか(データタイプはプログラム開始後のHaskellの "定数"

)です。

valuea::Int 
valuea = 120 

しかし、値がユーザーによって定義されていない場合、このメソッドは単に、動作します。私は、「変数を救う」ために知っている唯一の方法があります。事前に

おかげ

+2

'value = unsafePerformIO $ entryGetText myTextEntry'の何が問題なのですか? ( 'unsafePerformIO'はその環境に依存しないことを除いて) – chepner

+0

なぜunsafePerformIOを使用していますか? –

+6

あなたは理論的に純粋な言語で無害にコードを作成しようとしています。これは上り坂です。 – Carcigenicate

答えて

6

unsafePerformIO should be avoided at all costs、その実行が予測不可能であるとして。

ハスケルは純粋な言語であり、値は不変であるため、他の場所で突然変異したとして表示される値を「保存」することはできません。

代わりに、値を読み込み、必要に応じて値を渡す必要があります。

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

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

(そこ読者でこれを行うには、よりクリーンで慣用的な方法があるが、私は初心者レベルを目的としたこの答えを維持しようとしている)、ユーザから入力された

+3

ちょうどそれが答えで2回言及されて以来、私は関数に引数を渡すことはこれを行うために完全にきれいで慣用的な方法であると言いたいと思っていました(IMHO 'Reader'はほとんど抽象としてその重さを引き出しません) – jberryman

+1

ここで 'read'の' :: Double'アノテーション。その結果が '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 
関連する問題