diff --git a/Control/Monad/STLike/IO.hs b/Control/Monad/STLike/IO.hs
--- a/Control/Monad/STLike/IO.hs
+++ b/Control/Monad/STLike/IO.hs
@@ -2,11 +2,12 @@
     (-- * IOS monad
      IOS, io, runIOS
      -- * Regioned monad
-    ,Regioned, runRegion, region
+    ,Regioned, runRegion, region, unfoldRegion
      -- * Utilities
-    ,rbsFromPtr,rbsToBS,withRbsPtr,rbsMapLookup
+    ,RegionMonad, (:<), withRIOR, try, rbsFromPtr,rbsToBS,withRbsPtr,rbsMapLookup
     ) where
 
+import qualified Control.Exception as E
 import Control.Monad.STLike.Internal
 import Control.Monad.Trans
 import qualified Data.ByteString as B
@@ -27,10 +28,31 @@
 io :: IO t -> IOS s t
 io x = STLike x
 
+try :: IOS s t -> IOS s (Either E.SomeException t)
+try (STLike x) = STLike (E.try x)
+
 -- | Run an IOS computation in the IO monad.
 runIOS :: (forall s. IOS s t) -> IO t
 runIOS x = let STLike v = x in v
 
+{-
+-- | Use a resource with IOS. Like /bracket/.
+withRIOS :: (forall s. IOS (s :< o) (resource s))            -- ^ Open the resource
+            (forall s. (resource s -> IOS (s :< o) ()))      -- ^ Close it.
+            (forall s. (resource s -> IOS (s :< o) result))  -- ^ Compute with it.
+         -> IOS o result
+withRIOS (STLike open, close, work) = STLike (E.bracket open ioclose iowork)
+    where iowork  x = let STLike w = work  x in w
+          ioclose x = let STLike w = close x in w
+-}
+-- | Use a resource with IOS. Like /bracket/.
+withRIOR :: IOS o resource           -- ^ Open the resource
+         -> (resource -> IOS o ())   -- ^ Close it.
+         -> (forall s. Regioned (s:<o) resource -> IOS (s:<o) result) -- ^ Compute with it.
+         -> IOS o result
+withRIOR (STLike open) close work = STLike (E.bracket open ioclose iowork)
+    where iowork  x = let STLike w = work  (R x) in w
+          ioclose x = let STLike w = close x in w
 
 -- | Create a ByteString representing the pointer and length. 
 --   No copying done, O(1).
@@ -38,7 +60,7 @@
 rbsFromPtr ptr len = io $ fmap R $ B.unsafePackCStringLen (castPtr ptr,len)
 
 -- | Create a copy of a regioned ByteString as a normal ByteString. O(n).
-rbsToBS :: STLikeImpl m => Regioned s B.ByteString -> STLike m s B.ByteString
+rbsToBS :: RegionMonad m s reg => Regioned s B.ByteString -> STLike m reg B.ByteString
 rbsToBS (R b) = return $! B.copy b
 
 -- | Use a regioned ByteString as a pointer. O(1). 
@@ -49,7 +71,7 @@
 withRbsPtr (R b) act = io $ B.unsafeUseAsCStringLen b (\(p,l) -> let STLike v = (act (castPtr p) l) in v)
 
 -- | Lookup inside a Map with a regioned ByteString.
-rbsMapLookup :: (STLikeImpl m, Ord key) => Regioned s key -> M.Map key value -> STLike m s (Maybe value)
+rbsMapLookup :: (RegionMonad m s reg, Ord key) => Regioned s key -> M.Map key value -> STLike m reg (Maybe value)
 rbsMapLookup (R k) m = case M.lookup k m of
                       Just x  -> return (Just x)
                       Nothing -> return Nothing
diff --git a/Control/Monad/STLike/Internal.hs b/Control/Monad/STLike/Internal.hs
--- a/Control/Monad/STLike/Internal.hs
+++ b/Control/Monad/STLike/Internal.hs
@@ -2,8 +2,10 @@
 
 import Control.DeepSeq
 import Control.Monad
+import Data.Foldable(Foldable, toList)
 import Foreign
 
+
 -- | Regioned variables.
 -- A regioned variable is /safe/ i.e. no references to
 -- it may escape the current IOS.
@@ -18,12 +20,12 @@
 
 -- | Run a computation on regioned data
 -- and return the result in a strict fashion.
-runRegion :: (NotShared ty, STLikeImpl m) => Regioned s ty -> STLike m s ty
+runRegion :: (NotShared ty, RegionMonad m region s) => Regioned s ty -> STLike m region ty
 runRegion = runRegionImpl
 
 
 class NFData ty => NotShared ty where
-    runRegionImpl :: STLikeImpl m => Regioned s ty -> STLike m s ty
+    runRegionImpl :: RegionMonad m region s => Regioned s ty -> STLike m region ty
     runRegionImpl (R v) = v `deepseq` return v
 
 instance NotShared Bool
@@ -61,12 +63,15 @@
 --    runRegion (R bs) = return $! B.copy bs
 
 
-unsafeRemoveRegion :: STLikeImpl m => Regioned s r -> STLike m s r
+unsafeRemoveRegion :: RegionMonad m region s => Regioned s r -> STLike m region r
 unsafeRemoveRegion (R x) = return x
 
+unfoldRegion :: Foldable t => Regioned s (t a) -> [Regioned s a]
+unfoldRegion (R t) = map R (toList t)
+
 newtype STLike m s t = STLike (m t)
 
-class Monad m => STLikeImpl m
+class Monad m => STLikeImpl (m :: * -> *)
 
 instance STLikeImpl m => Monad (STLike m s) where
     (STLike a) >> (STLike b)   = STLike (a >> b)
@@ -77,4 +82,23 @@
 
 instance (STLikeImpl m) => Functor (STLike m s) where
     fmap f (STLike m) = STLike (liftM f m)
+
+
+
+data (:<) a b
+class STLikeImpl m => RegionMonad (m :: * -> *) region s
+instance STLikeImpl m => RegionMonad m s s
+instance (STLikeImpl m,
+          reg `TypeCast` (any :< rest),
+          RegionMonad m rest s)
+    => RegionMonad m reg s
+
+
+-- see http://okmij.org/ftp/Haskell/typecast.html
+class TypeCast   a b   | a -> b, b->a   where typeCast   :: a -> b
+class TypeCast'  t a b | t a -> b, t b -> a where typeCast'  :: t->a->b
+class TypeCast'' t a b | t a -> b, t b -> a where typeCast'' :: t->a->b
+instance TypeCast'  () a b => TypeCast a b where typeCast x = typeCast' () x
+instance TypeCast'' t a b => TypeCast' t a b where typeCast' = typeCast''
+instance TypeCast'' () a a where typeCast'' _ x  = x
 
diff --git a/Control/Monad/STLike/Unsafe.hs b/Control/Monad/STLike/Unsafe.hs
--- a/Control/Monad/STLike/Unsafe.hs
+++ b/Control/Monad/STLike/Unsafe.hs
@@ -1,5 +1,5 @@
 {-# OPTIONS_HADDOCK prune #-}
--- | Unsafe intersafe for implementators.
+-- | Unsafe interface for implementators.
 --   Purposefully not documented.
 module Control.Monad.STLike.Unsafe
     (STLike(..), STLikeImpl, NotShared(..), unsafeRemoveRegion
diff --git a/monad-stlike-io.cabal b/monad-stlike-io.cabal
--- a/monad-stlike-io.cabal
+++ b/monad-stlike-io.cabal
@@ -1,17 +1,26 @@
 Name:                monad-stlike-io
-Version:             0.1
+Version:             0.2.1
+Cabal-Version:       >= 1.6
+Build-Type:          Simple
 Synopsis:            ST-like monad capturing variables to regions and supporting IO.
 Description:         ST-like monad capturing variables to regions and supporting IO.
 License:             BSD3
 License-file:        COPYING
 Copyright:           Taru Karttunen <taruti@taruti.net>
 Author:              Taru Karttunen
-Category:            Regions, Monads
+Category:            Monadic Regions, Monads
 Maintainer:          taruti@taruti.net
-Build-Depends:       base >= 4 && < 5, bytestring, containers, deepseq, transformers
-Exposed-modules:     Control.Monad.STLike.IO,
-		     Control.Monad.STLike.Unsafe
-Other-modules:       Control.Monad.STLike.Internal
-Extensions:          RankNTypes, FlexibleInstances
-GHC-Options:         -Wall
-Build-Type:	     Simple
+Homepage:	     http://github.com/taruti/monad-stlike-io
+Source-repository head
+  type:     git
+  location: http://github.com/taruti/monad-stlike-io.git
+
+Library
+  Build-Depends:       base >= 4 && < 5, bytestring, containers, deepseq, transformers
+  Exposed-modules:     Control.Monad.STLike.IO,
+                       Control.Monad.STLike.Unsafe
+  Other-modules:       Control.Monad.STLike.Internal
+  Extensions:          RankNTypes, FlexibleInstances, TypeOperators, EmptyDataDecls, MultiParamTypeClasses,
+                       FunctionalDependencies, FlexibleContexts, UndecidableInstances, OverlappingInstances,
+                       KindSignatures
+  GHC-Options:         -Wall
