2016-04-12 8 views
1

私は、私が従うコースのためにハスケルで非常に小さな試合をしなければなりません。だから私は演奏機能を作りましたが、今はタイプシグネチャを変更するのに問題があります。ここでStateTモナドを正しく使うには?

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 

trueの場合、これはテスト用です。今、この関数は動作しますが、別の型シグネチャで動作させる必要があります。機能プレイの型シグネチャは次のようになります。

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

しかし、私はその後、私のStateTモナドを使用する方法について絶対にないアイデアを持っていませんか?これどうやってするの? IO (Either ParseError [[String]])モナドは、missingH-packageのparseFromFile関数の結果です。

+1

「再生」を変更する必要はありません。 'parseFromFile'を呼び出すのは、その結果に基づいて、' play'を呼び出すかどうかを決定する必要があります。 – chepner

+0

@chepnerしかし、 'IO(どちらかParseError [[String]])'の代わりに '[[String]]'を使ってplayを呼び出すことはできますか?私は '[[String]]'右へのアクセス権を持っていません。 –

+2

'lift :: IO(ParseError [[String]]) - > StateT GameState IO(どちらか...)'を使用して、モナドバインド( '>> ='または 'do'ブロック内)をonこの値。 'ParseError'に対処する必要があります。おそらく、例外を投げたり、モナドを' StateT GameState(ErrorT SomeErrorType IO) 'に変更してください。 – user2407038

答えて

4

発信者がそれを処理する必要があります。ところで

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

、あなたは実際にスコアを返すことはありませんので、playの戻り値の型はVoid、ないScoreでなければなりません。また、playの最後の行を削除し、戻り値の型を()に変更し、play inputforever (play input)に置き換えて再帰を強化する必要があります。ああ、あなたは決して入力を使用しません。

+0

ありがとうございました!これは期待通りに機能します:)入力は私がこの実装のplayに含まれていなかった別の関数で使われます;) –

関連する問題