In einem Monad-Transformer-Stack ExceptT
werden Bindungsausdrücke nach throwE
nicht ausgeführt.Ausgenommener Deadcode-Erkennung
- Stimmt das?
- Wenn ja, wie kann ich den Compiler oder meine Werkzeuge so konfigurieren, dass toter Code wie in diesem Beispiel erkannt wird?
{-# LANGUAGE
GeneralizedNewtypeDeriving
#-}
import Control.Monad.Except (MonadError (..), MonadIO, liftIO)
import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE)
newtype MyTrans e a = MyTrans { unMyTrans :: ExceptT e IO a }
deriving (Functor, Applicative, Monad, MonadIO, MonadError e)
throwMT :: e -> MyTrans e a
throwMT = MyTrans . throwE
runMyTrans :: MyTrans e a -> IO (Either e a)
runMyTrans = runExceptT . unMyTrans
comp = do
liftIO $ putStrLn "Starting Computation"
throwMT "Some Error"
-- dead code from this line
liftIO $ putStrLn "Ending Computation"
return()
main = print =<< runMyTrans comp
Sie werden definitiv ausgeführt, es ist nur so, dass sie als No-Op funktionieren. Wenn Sie diese Funktionalität nicht wünschen, verwenden Sie diese Funktion nicht. – 4castle
Ich verstehe es nicht, aus meiner Sicht wird nichts nach 'throwE' ausgewertet, zum Beispiel führt diese' throwMT "Some Error" >> = undefined' nicht zu einem Laufzeitfehler. – homam
Die Bindung wird ausgewertet, aber der Funktionsparameter wird ignoriert, wenn eine Ausnahme aufgetreten ist. Das ist Teil der Definition von "AusgenommenT". Man könnte es toten Code nennen, aber dieses Verhalten ist ein Punkt der Monade. – 4castle