2016-04-12 33 views
1

Takip ettiğim bir kurs için Haskell'de çok küçük bir oyun yapmalıyım. Bu yüzden oyun işlevini yarattım, ancak şimdi imzasını değiştirirken sorun yaşıyorum.StateT Monad'ı düzgün bir şekilde nasıl kullanabilirsiniz?

play :: [[String]] -> StateT GameState IO Score 
play input = 
do 
    liftIO $ clearScreen 
    (answered, correct) <- get 
    if True 
    then 
     do 
      liftIO $ putStrLn "Well done! Your answer was correct!" 
      liftIO $ putStrLn ("So far, you answered " ++ (show answered) ++ " questions") 
      put (answered + 1, correct + 1) 
      liftIO $ 
       do 
        temp <- getLine 
        putStrLn temp 
    else 
     do 
      liftIO $ putStrLn "I'm sorry, you're wrong..." 
      put (answered + 1, correct) 
    play input 

Şimdi, True deyimi olup olmadığını lütfen unutmayın, bu yalnızca sınama içindir. Şimdi bu işlev çalışıyor, ancak başka bir tür imza ile çalışmasını sağlamak zorundayım. Fonksiyon oyun türü imzası olmalıdır:

play :: IO (Either ParseError [[String]]) -> StateT GameState IO Score 

Ama sonra benim StateT monad nasıl kullanılacağına dair hiçbir fikrim yok? Bunu nasıl yapabilirim? IO (Either ParseError [[String]]) monad, eksikH paketinden parseFromFile işlevinin bir sonucudur.

+1

Neden 'play'i değiştirmeniz gerektiğini anlamıyorum. 'ParseFromFile' ifadesi ne olursa olsun, bu sonuca bağlı olarak, 'play' deyip aramayacağınıza karar vermelidir. – chepner

+0

@chepner Tamam, ama 'IO (Ya ParseError [[String]]) 'yerine' [[String]] 'ile nasıl çalabilirim? Ben [[String]] 'rightaway erişim hakkım yok. –

+2

'lift :: IO (Ya ParseError [[String]]) -> StateT GameState IO (Ya ...)' yi kullanabilir ve sonra monadic bind ('>> =' veya 'do' bloğun içinde) kullanabilirsiniz. Bu değer. Yine de 'ParseError' ile uğraşmanız gerekecek - belki de bir istisna atıyor veya monadınızı' StateT GameState (ErrorT SomeErrorType IO) ' – user2407038

cevap

4

Arayan kişi bunu işlemelidir. play dönüş tipi Void değil Score olmalıdır böylece

arada
main :: IO() 
main = do 
    parsed <- parseFromFileStuff 
    case parsed of 
    Left parseerror -> handleErrorStuff 
    Right input -> evalStateT (play input) initialState 

, aslında, bir skor asla geri. Ayrıca, play s son satırını kaldırarak, dönüş türünü () olarak değiştirerek ve play input'u forever (play input) ile değiştirerek bu yinelemeyi sıkmanız gerekir. Oh ve asla girişi kullanmazsın.

+0

'a çeviriyor! Çok teşekkür ederim! Bu beklendiği gibi çalışır :) Giriş, bu oyun uygulamasına dahil etmediğim başka bir işlevde kullanılır;) –