diff --git a/UnexceptionalIO.hs b/UnexceptionalIO.hs
--- a/UnexceptionalIO.hs
+++ b/UnexceptionalIO.hs
@@ -204,8 +204,9 @@
 instance Monad UIO where
 	return = UIO . return
 	(UIO x) >>= f = UIO (x >>= run . f)
-
+#if !MIN_VERSION_base(4,13,0)
 	fail s = error $ "UnexceptionalIO cannot fail (" ++ s ++ ")"
+#endif
 
 instance MonadFix UIO where
 	mfix f = UIO (mfix $ run . f)
@@ -231,10 +232,7 @@
 	(SomeNonPseudoException -> e) -- ^ Default if an unexpected exception occurs
 	-> IO a
 	-> m (Either e a)
-fromIO' f = (return . either (\e -> Left $ fromMaybe (f e) $ castException e) Right) <=< fromIO
-
-castException :: (Ex.Exception e1, Ex.Exception e2) => e1 -> Maybe e2
-castException = Ex.fromException . Ex.toException
+fromIO' f = liftM (either (Left . f) id) . fromIO . try
 #endif
 
 -- | Re-embed 'UIO' into 'IO'
@@ -297,6 +295,9 @@
 		-- Non-async PseudoException, so wrap in an async wrapper before
 		-- throwing async'ly
 		| otherwise = unsafeFromIO $ Concurrent.throwTo parent (ChildThreadError e)
+
+castException :: (Ex.Exception e1, Ex.Exception e2) => e1 -> Maybe e2
+castException = Ex.fromException . Ex.toException
 
 -- | Async signal that a child thread ended due to non-async PseudoException
 newtype ChildThreadError = ChildThreadError PseudoException deriving (Show, Typeable)
diff --git a/unexceptionalio.cabal b/unexceptionalio.cabal
--- a/unexceptionalio.cabal
+++ b/unexceptionalio.cabal
@@ -1,5 +1,5 @@
 name:            unexceptionalio
-version:         0.5.0
+version:         0.5.1
 cabal-version:   >=1.10
 license:         OtherLicense
 license-file:    COPYING
@@ -40,6 +40,7 @@
         main-is:     tests/suite.hs
         ghc-options: -O0 -fno-warn-tabs
         default-language: Haskell2010
+        other-modules: UnexceptionalIO
 
         build-depends:
                 base == 4.*,
