2016-04-04 11 views
1

Servantで削除操作を実行して、エラーまたは()を戻したいとします。ここに私のコードは次のとおりです。タイプが一致しません。必ずliftIOを使用する必要がありますか?

del :: Int -> ExceptT ServantErr IO() 
del myId = liftIO $ do 
    cn <- getConnection 
    a <- execute cn "delete from table1 where id = ?" [myId] 
    case a of 
    1 -> return() 
    _ -> throwE err503 --compile error 

エラーは次のとおりです。

Couldn't match expected type ‘IO()’ 
       with actual type ‘ExceptT ServantErr m0 a0’ 
    In the expression: throwE err503 
    In a case alternative: _ -> throwE err503 

私は可能であればそれぞれの式の前にliftIOを使用することを希望されない:

del myId = do 
    cn <- liftIO getConnection 
    a <- liftIO $ execute cn "delete from table1 where id = ?" [myId] 
    case a of 
    1 -> return() 
    _ -> throwE err503 

私は、エラーを返すことができますどのように?

答えて

7

私はあなたがそれを避けることはできないと思います。すべての行がIOでなければなりません初期

del :: Int -> ExceptT ServantErr IO() 
del myId = liftIO $ do ... 

となるようdoブロックでEverthingは、同じモナドである必要があります。しかし、さまざまな方法で物事を並べ替えることができます。いくつかのものが一緒に来る下位IOブロック、と:Control.Monad.unless

del myId = do 
    a <- liftIO $ do 
    cn <- getConnection 
    execute cn "delete from table1 where id = ?" [myId] 
    case a of 
    1 -> return() 
    _ -> throwE err503 

か、と言う:

del myId = do 
    a <- liftIO $ do 
    cn <- getConnection 
    execute cn "delete from table1 where id = ?" [myId] 
    unless (a == 1) $ throwE err503 

や他のいくつかの方法。あなたはgetConnectionexecuteのどちらを使っているのかは言わないが、それらはまだMonadIO m => m ..ではないと確信していますか?結局のところ、liftIOを削除することはできますか?

関連する問題