diff --git a/hoppy-std.cabal b/hoppy-std.cabal
--- a/hoppy-std.cabal
+++ b/hoppy-std.cabal
@@ -1,5 +1,5 @@
 name: hoppy-std
-version: 0.1.0
+version: 0.2.0
 synopsis: C++ FFI generator - Standard library bindings
 homepage: http://khumba.net/projects/hoppy
 license: Apache-2.0
@@ -38,7 +38,7 @@
       base >=4.7 && <4.9
     , filepath >=1.0 && <1.5
     , haskell-src >=1.0 && <1.1
-    , hoppy-generator >=0.1 && <0.2
+    , hoppy-generator >=0.2 && <0.3
   hs-source-dirs: src
   ghc-options: -W -fwarn-incomplete-patterns -fwarn-unused-do-bind
   default-language: Haskell2010
diff --git a/src/Foreign/Hoppy/Generator/Std.hs b/src/Foreign/Hoppy/Generator/Std.hs
--- a/src/Foreign/Hoppy/Generator/Std.hs
+++ b/src/Foreign/Hoppy/Generator/Std.hs
@@ -30,12 +30,12 @@
 -- the collection as a whole.
 data ValueConversion =
     ConvertPtr
-    -- ^ A C++ value of type @t@ will convert to a foreign value of type @'TPtr'
-    -- t@.
+    -- ^ A C++ value of type @t@ will convert to a foreign value of type
+    -- @'Foreign.Hoppy.Generator.Types.ptrT' t@.
   | ConvertValue
     -- ^ A C++ value of type @t@ will convert to a foreign value of type @t@.
-    -- For an object type ('TObj'), the class must have conversions
-    -- ('ClassConversion').
+    -- For an object type ('Foreign.Hoppy.Generator.Types.objT'), the class must
+    -- have conversions ('ClassConversion').
   deriving (Bounded, Enum, Eq, Ord, Show)
 
 -- | Include @std::string@.
diff --git a/src/Foreign/Hoppy/Generator/Std/Iterator.hs b/src/Foreign/Hoppy/Generator/Std/Iterator.hs
--- a/src/Foreign/Hoppy/Generator/Std/Iterator.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Iterator.hs
@@ -40,7 +40,7 @@
     OpSubtract,
     OpSubtractAssign),
   Purity (Nonpure),
-  Type (TConst, TObj, TObjToHeap, TPtr, TRef, TVoid),
+  Type,
   addReqIncludes,
   classAddCtors,
   classAddMethods,
@@ -54,6 +54,7 @@
   ClassFeature (Assignable, Copyable, Equatable),
   classAddFeatures,
   )
+import Foreign.Hoppy.Generator.Types
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 
 -- | Whether an iterator may be used to modify the underlying collection.
@@ -67,13 +68,13 @@
 --
 -- * The class features 'Assignable', 'Copyable', and 'Equatable'.
 --
--- * __operator*:__ @getConst :: this -> 'TRef' ('TConst' valueType)@; if
+-- * __operator*:__ @getConst :: this -> 'refT' ('constT' valueType)@; if
 -- @valueTypeMaybe@ is present.
 --
--- * __operator*:__ @get :: this -> 'TRef' valueType@; if @valueTypeMaybe@ is
+-- * __operator*:__ @get :: this -> 'refT' valueType@; if @valueTypeMaybe@ is
 -- present and @mutable@ is 'Mutable'.
 --
--- * __*iter = x:__ @put :: this -> valueType -> 'TVoid'@; if @valueTypeMaybe@
+-- * __*iter = x:__ @put :: this -> valueType -> 'voidT'@; if @valueTypeMaybe@
 -- is present and @mutable@ is 'Mutable'.
 makeTrivialIterator :: IteratorMutability -> Maybe Type -> Class -> Class
 makeTrivialIterator mutable valueTypeMaybe cls =
@@ -90,58 +91,58 @@
           catMaybes
           [ do valueType <- valueTypeMaybe
                Mutable <- Just mutable
-               return $ mkMethod' OpDeref "get" [] $ TRef valueType
+               return $ mkMethod' OpDeref "get" [] $ refT valueType
           , do valueType <- valueTypeMaybe
-               return $ mkConstMethod' OpDeref "getConst" [] $ TRef $ TConst valueType
+               return $ mkConstMethod' OpDeref "getConst" [] $ refT $ constT valueType
           , do valueType <- valueTypeMaybe
                Mutable <- Just mutable
                return $
                  makeFnMethod (ident2 "hoppy" "iterator" "put") "put"
-                 MNormal Nonpure [TPtr $ TObj cls, valueType] TVoid
+                 MNormal Nonpure [ptrT $ objT cls, valueType] voidT
           ]
 
 -- | Turns a class into a forward iterator, including everything from
 -- 'makeTrivialIterator' plus the pre-increment operator:
 --
--- * __operator++:__ @next :: this -> 'TRef' ('TObj' cls)@.
+-- * __operator++:__ @next :: this -> 'refT' ('objT' cls)@.
 makeForwardIterator :: IteratorMutability -> Maybe Type -> Class -> Class
 makeForwardIterator mutable valueTypeMaybe cls =
   classAddMethods methods $
   makeTrivialIterator mutable valueTypeMaybe cls
   where methods =
-          [ mkMethod' OpIncPre "next" [] $ TRef $ TObj cls
+          [ mkMethod' OpIncPre "next" [] $ refT $ objT cls
           ]
 
 -- | Turns a class into a bidirectional iterator, including everything from
 -- 'makeForwardIterator' plus the pre-decrement operator:
 --
--- * __operator--:__ @prev :: this -> 'TRef' ('TObj' cls)@.
+-- * __operator--:__ @prev :: this -> 'refT' ('objT' cls)@.
 makeBidirectionalIterator :: IteratorMutability -> Maybe Type -> Class -> Class
 makeBidirectionalIterator mutability valueTypeMaybe cls =
   classAddMethods methods $
   makeForwardIterator mutability valueTypeMaybe cls
   where methods =
-          [ mkMethod' OpDecPre "prev" [] $ TRef $ TObj cls
+          [ mkMethod' OpDecPre "prev" [] $ refT $ objT cls
           ]
 
 -- | @makeRandomIterator mutable valueTypeMaybe distanceType cls@ turns a class
 -- into a random iterator, including everything from 'makeBidirectionalIterator'
 -- plus some methods:
 --
--- * __operator+=:__ @add :: this -> distanceType -> 'TRef' ('TObj' cls)@.
+-- * __operator+=:__ @add :: this -> distanceType -> 'refT' ('objT' cls)@.
 --
--- * __operator+:__ @plusNew :: this -> distanceType -> 'TObjToHeap' cls@.
+-- * __operator+:__ @plus :: this -> distanceType -> 'toGcT' cls@.
 --
--- * __operator-=:__ @subtract :: distanceType -> 'TRef' ('TObj' cls)@.
+-- * __operator-=:__ @subtract :: distanceType -> 'refT' ('objT' cls)@.
 --
--- * __operator-:__ @minusNew :: distanceType -> 'TObjToHeap' cls@.
+-- * __operator-:__ @minus :: distanceType -> 'toGcT' cls@.
 --
 -- * __operator-:__ @difference :: this -> this -> distanceType@.
 --
--- * __operator[]:__ @atConst :: distanceType -> 'TRef' ('TConst' valueType)@;
+-- * __operator[]:__ @atConst :: distanceType -> 'refT' ('constT' valueType)@;
 -- if @valueTypeMaybe@ is present.
 --
--- * __operator[]:__ @at :: distanceType -> 'TRef' valueType@; if
+-- * __operator[]:__ @at :: distanceType -> 'refT' valueType@; if
 -- @valueTypeMaybe@ is present and @mutable@ is 'Mutable'.
 makeRandomIterator :: IteratorMutability -> Maybe Type -> Type -> Class -> Class
 makeRandomIterator mutable valueTypeMaybe distanceType cls =
@@ -149,14 +150,14 @@
   makeBidirectionalIterator mutable valueTypeMaybe cls
   where methods =
           catMaybes
-          [ Just $ mkMethod' OpAdd "plusNew" [distanceType] $ TObjToHeap cls
-          , Just $ mkMethod' OpAddAssign "add" [distanceType] $ TRef $ TObj cls
-          , Just $ mkMethod' OpSubtract "minusNew" [distanceType] $ TObjToHeap cls
-          , Just $ mkMethod' OpSubtract "difference" [TObj cls] distanceType
-          , Just $ mkMethod' OpSubtractAssign "subtract" [distanceType] $ TRef $ TObj cls
+          [ Just $ mkMethod' OpAdd "plus" [distanceType] $ toGcT $ objT cls
+          , Just $ mkMethod' OpAddAssign "add" [distanceType] $ refT $ objT cls
+          , Just $ mkMethod' OpSubtract "minus" [distanceType] $ toGcT $ objT cls
+          , Just $ mkMethod' OpSubtract "difference" [objT cls] distanceType
+          , Just $ mkMethod' OpSubtractAssign "subtract" [distanceType] $ refT $ objT cls
           , do valueType <- valueTypeMaybe
                Mutable <- Just mutable
-               return $ mkMethod' OpArray "at" [distanceType] $ TRef valueType
+               return $ mkMethod' OpArray "at" [distanceType] $ refT valueType
           , do valueType <- valueTypeMaybe
-               return $ mkConstMethod' OpArray "atConst" [distanceType] $ TRef $ TConst valueType
+               return $ mkConstMethod' OpArray "atConst" [distanceType] $ refT $ constT valueType
           ]
diff --git a/src/Foreign/Hoppy/Generator/Std/List.hs b/src/Foreign/Hoppy/Generator/Std/List.hs
--- a/src/Foreign/Hoppy/Generator/Std/List.hs
+++ b/src/Foreign/Hoppy/Generator/Std/List.hs
@@ -49,6 +49,7 @@
   )
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Iterator
+import Foreign.Hoppy.Generator.Types
 import Foreign.Hoppy.Generator.Version (collect, just, test)
 
 -- | Options for instantiating the list classes.
@@ -97,43 +98,41 @@
         [ mkCtor "new" []
         ] $
         collect
-        [ just $ mkMethod' "back" "back" [] $ TRef t
-        , just $ mkConstMethod' "back" "backConst" [] $ TRef $ TConst t
-        , just $ mkMethod' "begin" "begin" [] $ TObjToHeap iterator
-        , just $ mkConstMethod' "begin" "beginConst" [] $ TObjToHeap constIterator
-        , just $ mkMethod "clear" [] TVoid
-        , just $ mkConstMethod "empty" [] TBool
-        , just $ mkMethod' "end" "end" [] $ TObjToHeap iterator
-        , just $ mkConstMethod' "end" "endConst" [] $ TObjToHeap constIterator
-        , just $ mkMethod' "erase" "erase" [TObj iterator] TVoid
-        , just $ mkMethod' "erase" "eraseRange" [TObj iterator, TObj iterator] TVoid
-        , just $ mkMethod' "front" "front" [] $ TRef t
-        , just $ mkConstMethod' "front" "frontConst" [] $ TRef $ TConst t
-        , just $ mkMethod' "insert" "insert" [TObj iterator, t] TVoid
-        , just $ mkMethod' "insert" "insertAndGetIterator"
-          [TObj iterator, t] $ TObjToHeap iterator
-        , just $ mkConstMethod' "max_size" "maxSize" [] TSize
-        , test (elem Comparable features) $ mkMethod "merge" [TRef $ TObj list] TVoid
+        [ just $ mkMethod' "back" "back" [] $ refT t
+        , just $ mkConstMethod' "back" "backConst" [] $ refT $ constT t
+        , just $ mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
+        , just $ mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
+        , just $ mkMethod "clear" [] voidT
+        , just $ mkConstMethod "empty" [] boolT
+        , just $ mkMethod' "end" "end" [] $ toGcT $ objT iterator
+        , just $ mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        , just $ mkMethod' "erase" "erase" [objT iterator] voidT
+        , just $ mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
+        , just $ mkMethod' "front" "front" [] $ refT t
+        , just $ mkConstMethod' "front" "frontConst" [] $ refT $ constT t
+        , just $ mkMethod "insert" [objT iterator, t] $ toGcT $ objT iterator
+        , just $ mkConstMethod' "max_size" "maxSize" [] sizeT
+        , test (elem Comparable features) $ mkMethod "merge" [refT $ objT list] voidT
           -- TODO merge(list&, Comparator)
-        , just $ mkMethod' "pop_back" "popBack" [] TVoid
-        , just $ mkMethod' "pop_front" "popFront" [] TVoid
-        , just $ mkMethod' "push_back" "pushBack" [t] TVoid
-        , just $ mkMethod' "push_front" "pushFront" [t] TVoid
-        , test (elem Equatable features) $ mkMethod "remove" [t] TVoid
+        , just $ mkMethod' "pop_back" "popBack" [] voidT
+        , just $ mkMethod' "pop_front" "popFront" [] voidT
+        , just $ mkMethod' "push_back" "pushBack" [t] voidT
+        , just $ mkMethod' "push_front" "pushFront" [t] voidT
+        , test (elem Equatable features) $ mkMethod "remove" [t] voidT
           -- TODO remove_if(UnaryPredicate)
-        , just $ mkMethod' "resize" "resize" [TSize] TVoid
-        , just $ mkMethod' "resize" "resizeWith" [TSize, t] TVoid
-        , just $ mkMethod "reverse" [] TVoid
-        , just $ mkConstMethod "size" [] TSize
-        , test (elem Comparable features) $ mkMethod "sort" [] TVoid
+        , just $ mkMethod' "resize" "resize" [sizeT] voidT
+        , just $ mkMethod' "resize" "resizeWith" [sizeT, t] voidT
+        , just $ mkMethod "reverse" [] voidT
+        , just $ mkConstMethod "size" [] sizeT
+        , test (elem Comparable features) $ mkMethod "sort" [] voidT
           -- TODO sort(Comparator)
-        , just $ mkMethod' "splice" "spliceAll" [TObj iterator, TRef $ TObj list] TVoid
+        , just $ mkMethod' "splice" "spliceAll" [objT iterator, refT $ objT list] voidT
         , just $ mkMethod' "splice" "spliceOne"
-          [TObj iterator, TRef $ TObj list, TObj iterator] TVoid
+          [objT iterator, refT $ objT list, objT iterator] voidT
         , just $ mkMethod' "splice" "spliceRange"
-          [TObj iterator, TRef $ TObj list, TObj iterator, TObj iterator] TVoid
-        , just $ mkMethod "swap" [TRef $ TObj list] TVoid
-        , test (Equatable `elem` features) $ mkMethod "unique" [] TVoid
+          [objT iterator, refT $ objT list, objT iterator, objT iterator] voidT
+        , just $ mkMethod "swap" [refT $ objT list] voidT
+        , test (Equatable `elem` features) $ mkMethod "unique" [] voidT
           -- TODO unique(BinaryPredicate)
         ]
 
@@ -149,10 +148,10 @@
         makeClass (identT' [("std", Nothing), ("list", Just [t]), ("const_iterator", Nothing)])
         (Just $ toExtName constIteratorName)
         []
-        [ mkCtor "newFromConst" [TObj iterator]
+        [ mkCtor "newFromConst" [objT iterator]
         ]
         [ makeFnMethod (ident2 "hoppy" "iterator" "deconst") "deconst" MConst Nonpure
-          [TObj constIterator, TRef $ TObj list] $ TObjToHeap iterator
+          [objT constIterator, refT $ objT list] $ toGcT $ objT iterator
         ]
 
       -- The addendum for the list class contains HasContents and FromContents
@@ -169,10 +168,10 @@
           hsValueType <-
             cppTypeToHsTypeAndUse HsHsSide $
             (case conversion of
-               ConvertPtr -> TPtr
+               ConvertPtr -> ptrT
                ConvertValue -> id) $
             case cst of
-              Const -> TConst t
+              Const -> constT t
               Nonconst -> t
 
           -- Generate const and nonconst HasContents instances.
@@ -195,12 +194,10 @@
                     Const -> "getConst"
                     Nonconst -> "get"
               saysLn ["empty' <- ", toHsMethodName' list "empty", " this'"]
-              sayLn "if empty' then HoppyP.return [] else"
+              sayLn "if empty' then HoppyP.return [] else do"
               indent $ do
-                saysLn ["HoppyFHR.withScopedPtr (", toHsMethodName' list listBegin,
-                        " this') $ \\begin' ->"]
-                saysLn ["HoppyFHR.withScopedPtr (", toHsMethodName' list listEnd,
-                        " this') $ \\iter' ->"]
+                saysLn ["begin' <- ", toHsMethodName' list listBegin, " this'"]
+                saysLn ["iter' <- ", toHsMethodName' list listEnd, " this'"]
                 sayLn "go' iter' begin' []"
               sayLn "where"
               indent $ do
diff --git a/src/Foreign/Hoppy/Generator/Std/Map.hs b/src/Foreign/Hoppy/Generator/Std/Map.hs
--- a/src/Foreign/Hoppy/Generator/Std/Map.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Map.hs
@@ -50,6 +50,7 @@
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 import Foreign.Hoppy.Generator.Std.Iterator
+import Foreign.Hoppy.Generator.Types
 
 -- | Options for instantiating the map classes.
 data Options = Options
@@ -111,28 +112,28 @@
         makeClass (ident1T "std" "map" [k, v]) (Just extName) []
         [ mkCtor "new" []
         ]
-        [ mkMethod' "at" "at" [k] $ TRef v
-        , mkConstMethod' "at" "atConst" [k] $ TRef $ TConst v
-        , mkMethod' "begin" "begin" [] $ TObjToHeap iterator
-        , mkConstMethod' "begin" "beginConst" [] $ TObjToHeap constIterator
-        , mkMethod "clear" [] TVoid
-        , mkConstMethod "count" [k] TSize
-        , mkConstMethod "empty" [] TBool
-        , mkMethod' "end" "end" [] $ TObjToHeap iterator
-        , mkConstMethod' "end" "endConst" [] $ TObjToHeap constIterator
+        [ mkMethod' "at" "at" [k] $ refT v
+        , mkConstMethod' "at" "atConst" [k] $ refT $ constT v
+        , mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
+        , mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
+        , mkMethod "clear" [] voidT
+        , mkConstMethod "count" [k] sizeT
+        , mkConstMethod "empty" [] boolT
+        , mkMethod' "end" "end" [] $ toGcT $ objT iterator
+        , mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
           -- equal_range: find is good enough.
-        , mkMethod' "erase" "erase" [TObj iterator] TVoid
-        , mkMethod' "erase" "eraseKey" [k] TSize
-        , mkMethod' "erase" "eraseRange" [TObj iterator, TObj iterator] TVoid
-        , mkMethod' "find" "find" [k] $ TObjToHeap iterator
-        , mkConstMethod' "find" "findConst" [k] $ TObjToHeap constIterator
+        , mkMethod' "erase" "erase" [objT iterator] voidT
+        , mkMethod' "erase" "eraseKey" [k] sizeT
+        , mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
+        , mkMethod' "find" "find" [k] $ toGcT $ objT iterator
+        , mkConstMethod' "find" "findConst" [k] $ toGcT $ objT constIterator
           -- TODO insert
           -- lower_bound: find is good enough.
-        , mkConstMethod' "max_size" "maxSize" [] TSize
-        , mkConstMethod "size" [] TSize
-        , mkMethod "swap" [TRef $ TObj map] TVoid
+        , mkConstMethod' "max_size" "maxSize" [] sizeT
+        , mkConstMethod "size" [] sizeT
+        , mkMethod "swap" [refT $ objT map] voidT
           -- upper_bound: find is good enough.
-        , mkMethod OpArray [k] $ TRef v
+        , mkMethod OpArray [k] $ refT v
         ]
 
       iterator =
@@ -143,11 +144,11 @@
                             ("iterator", Nothing)])
         (Just $ toExtName iteratorName) [] []
         [ makeFnMethod getIteratorKeyIdent "getKey" MConst Nonpure
-          [TObj iterator] $ TRef $ TConst k
+          [objT iterator] $ refT $ constT k
         , makeFnMethod getIteratorValueIdent "getValue" MNormal Nonpure
-          [TRef $ TObj iterator] $ TRef v
+          [refT $ objT iterator] $ refT v
         , makeFnMethod getIteratorValueIdent "getValueConst" MConst Nonpure
-          [TObj iterator] $ TRef $ TConst v
+          [objT iterator] $ refT $ constT v
         ]
 
       constIterator =
@@ -158,14 +159,14 @@
                             ("const_iterator", Nothing)])
         (Just $ toExtName constIteratorName)
         []
-        [ mkCtor "newFromConst" [TObj iterator]
+        [ mkCtor "newFromConst" [objT iterator]
         ]
         [ makeFnMethod (ident2 "hoppy" "iterator" "deconst") "deconst" MConst Nonpure
-          [TObj constIterator, TRef $ TObj map] $ TObjToHeap iterator
+          [objT constIterator, refT $ objT map] $ toGcT $ objT iterator
         , makeFnMethod getIteratorKeyIdent "getKey" MConst Nonpure
-          [TObj constIterator] $ TRef $ TConst k
+          [objT constIterator] $ refT $ constT k
         , makeFnMethod getIteratorValueIdent "getValueConst" MConst Nonpure
-          [TObj constIterator] $ TRef $ TConst v
+          [objT constIterator] $ refT $ constT v
         ]
 
       -- The addendum for the map class contains HasContents and FromContents
@@ -181,17 +182,17 @@
           keyHsType <-
             cppTypeToHsTypeAndUse HsHsSide $
             (case keyConv of
-               ConvertPtr -> TPtr
+               ConvertPtr -> ptrT
                ConvertValue -> id) $
-            TConst k
+            constT k
 
           valueHsType <-
             cppTypeToHsTypeAndUse HsHsSide $
             (case valueConv of
-               ConvertPtr -> TPtr
+               ConvertPtr -> ptrT
                ConvertValue -> id) $
             case cst of
-              Const -> TConst v
+              Const -> constT v
               Nonconst -> v
 
           -- Generate const and nonconst HasContents instances.
@@ -214,12 +215,10 @@
                     Const -> "getValueConst"
                     Nonconst -> "getValue"
               saysLn ["empty' <- ", toHsMethodName' map "empty", " this'"]
-              sayLn "if empty' then HoppyP.return [] else"
+              sayLn "if empty' then HoppyP.return [] else do"
               indent $ do
-                saysLn ["HoppyFHR.withScopedPtr (", toHsMethodName' map mapBegin,
-                        " this') $ \\begin' ->"]
-                saysLn ["HoppyFHR.withScopedPtr (", toHsMethodName' map mapEnd,
-                        " this') $ \\iter' ->"]
+                saysLn ["begin' <- ", toHsMethodName' map mapBegin, " this'"]
+                saysLn ["iter' <- ", toHsMethodName' map mapEnd, " this'"]
                 sayLn "go' iter' begin' []"
               sayLn "where"
               indent $ do
diff --git a/src/Foreign/Hoppy/Generator/Std/Pair.hs b/src/Foreign/Hoppy/Generator/Std/Pair.hs
--- a/src/Foreign/Hoppy/Generator/Std/Pair.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Pair.hs
@@ -35,6 +35,7 @@
   classAddFeatures,
   )
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
+import Foreign.Hoppy.Generator.Types
 import Foreign.Hoppy.Generator.Version (CppVersion (Cpp2011), activeCppVersion, collect, just, test)
 
 -- | Options for instantiating @pair@.
@@ -77,14 +78,14 @@
         ] $
         collect
         [ just $ makeFnMethod (ident2 "hoppy" "utility" "pairFirst") "first" MNormal Nonpure
-          [TRef $ TObj pair] $ TRef a
+          [refT $ objT pair] $ refT a
         , just $ makeFnMethod (ident2 "hoppy" "utility" "pairFirst") "firstConst" MConst Nonpure
-          [TRef $ TObj pair] $ TRef $ TConst a
+          [refT $ objT pair] $ refT $ constT a
         , just $ makeFnMethod (ident2 "hoppy" "utility" "pairSecond") "second" MNormal Nonpure
-          [TRef $ TObj pair] $ TRef b
+          [refT $ objT pair] $ refT b
         , just $ makeFnMethod (ident2 "hoppy" "utility" "pairSecond") "secondConst" MConst Nonpure
-          [TRef $ TObj pair] $ TRef $ TConst b
-        , test (activeCppVersion >= Cpp2011) $ mkMethod "swap" [TRef $ TObj pair] TVoid
+          [refT $ objT pair] $ refT $ constT b
+        , test (activeCppVersion >= Cpp2011) $ mkMethod "swap" [refT $ objT pair] voidT
         ]
 
   in Contents
diff --git a/src/Foreign/Hoppy/Generator/Std/Set.hs b/src/Foreign/Hoppy/Generator/Std/Set.hs
--- a/src/Foreign/Hoppy/Generator/Std/Set.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Set.hs
@@ -51,6 +51,7 @@
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Internal (includeHelper)
 import Foreign.Hoppy.Generator.Std.Iterator
+import Foreign.Hoppy.Generator.Types
 
 -- | Options for instantiating the set classes.
 data Options = Options
@@ -98,24 +99,25 @@
         makeClass (ident1T "std" "set" [t]) (Just $ toExtName setName) []
         [ mkCtor "new" []
         ]
-        [ mkConstMethod "begin" [] $ TObjToHeap iterator
-        , mkMethod "clear" [] TVoid
-        , mkConstMethod "count" [t] TSize
+        [ mkConstMethod "begin" [] $ toGcT $ objT iterator
+        , mkMethod "clear" [] voidT
+        , mkConstMethod "count" [t] sizeT
           -- TODO count
-        , mkConstMethod "empty" [] TBool
-        , mkConstMethod "end" [] $ TObjToHeap iterator
+        , mkConstMethod "empty" [] boolT
+        , mkConstMethod "end" [] $ toGcT $ objT iterator
           -- equalRange: find is good enough.
-        , mkMethod' "erase" "erase" [TObj iterator] TVoid
-        , mkMethod' "erase" "eraseRange" [TObj iterator, TObj iterator] TVoid
-        , mkMethod "find" [t] $ TObjToHeap iterator
+        , mkMethod' "erase" "erase" [objT iterator] voidT
+        , mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
+        , mkMethod "find" [t] $ toGcT $ objT iterator
+          -- TODO Replace these with a single version that returns a (toGcT std::pair).
         , makeFnMethod (ident2 "hoppy" "set" "insert") "insert"
-          MNormal Nonpure [TRef $ TObj set, t] TBool
+          MNormal Nonpure [refT $ objT set, t] boolT
         , makeFnMethod (ident2 "hoppy" "set" "insertAndGetIterator") "insertAndGetIterator"
-          MNormal Nonpure [TRef $ TObj set, t] $ TObjToHeap iterator
+          MNormal Nonpure [refT $ objT set, t] $ toGcT $ objT iterator
           -- lower_bound: find is good enough.
-        , mkConstMethod' "max_size" "maxSize" [] TSize
-        , mkConstMethod "size" [] TSize
-        , mkMethod "swap" [TRef $ TObj set] TVoid
+        , mkConstMethod' "max_size" "maxSize" [] sizeT
+        , mkConstMethod "size" [] sizeT
+        , mkMethod "swap" [refT $ objT set] voidT
           -- upper_bound: find is good enough.
         ]
 
@@ -141,10 +143,10 @@
         [hsValueTypeConst, hsValueType] <- forM [Const, Nonconst] $ \cst ->
             cppTypeToHsTypeAndUse HsHsSide $
             (case conversion of
-               ConvertPtr -> TPtr
+               ConvertPtr -> ptrT
                ConvertValue -> id) $
             case cst of
-              Const -> TConst t
+              Const -> constT t
               Nonconst -> t
 
         -- Generate const and nonconst HasContents instances.
@@ -155,12 +157,10 @@
           sayLn "toContents this' = do"
           indent $ do
             saysLn ["empty' <- ", toHsMethodName' set "empty", " this'"]
-            sayLn "if empty' then HoppyP.return [] else"
+            sayLn "if empty' then HoppyP.return [] else do"
             indent $ do
-              saysLn ["HoppyFHR.withScopedPtr (", toHsMethodName' set "begin",
-                      " this') $ \\begin' ->"]
-              saysLn ["HoppyFHR.withScopedPtr (", toHsMethodName' set "end",
-                      " this') $ \\iter' ->"]
+              saysLn ["begin' <- ", toHsMethodName' set "begin", " this'"]
+              saysLn ["iter' <- ", toHsMethodName' set "end", " this'"]
               sayLn "go' iter' begin' []"
             sayLn "where"
             indent $ do
diff --git a/src/Foreign/Hoppy/Generator/Std/String.hs b/src/Foreign/Hoppy/Generator/Std/String.hs
--- a/src/Foreign/Hoppy/Generator/Std/String.hs
+++ b/src/Foreign/Hoppy/Generator/Std/String.hs
@@ -25,6 +25,7 @@
 import Foreign.Hoppy.Generator.Language.Haskell (addImports, sayLn)
 import Foreign.Hoppy.Generator.Spec
 import Foreign.Hoppy.Generator.Spec.ClassFeature
+import Foreign.Hoppy.Generator.Types
 import Language.Haskell.Syntax (
   HsName (HsIdent),
   HsQName (UnQual),
@@ -36,27 +37,25 @@
 c_string =
   addReqIncludes [includeStd "string"] $
   classAddFeatures [Assignable, Comparable, Copyable, Equatable] $
-  classModifyConversion
-  (\c -> c { classHaskellConversion =
-             Just ClassHaskellConversion
-             { classHaskellConversionType = do
-               addImports hsImportForPrelude
-               return $ HsTyCon $ UnQual $ HsIdent "HoppyP.String"
-             , classHaskellConversionToCppFn = do
-               addImports $ mconcat [hsImportForPrelude, hsImportForForeignC]
-               sayLn "HoppyP.flip HoppyFC.withCString stdString_newFromCString"
-             , classHaskellConversionFromCppFn = do
-               addImports $ mconcat [hsImport1 "Control.Monad" "(<=<)", hsImportForForeignC]
-               sayLn "HoppyFC.peekCString <=< stdString_c_str"
-             }
-           }) $
+  classSetHaskellConversion
+    ClassHaskellConversion
+      { classHaskellConversionType = do
+        addImports hsImportForPrelude
+        return $ HsTyCon $ UnQual $ HsIdent "HoppyP.String"
+      , classHaskellConversionToCppFn = do
+        addImports $ mconcat [hsImportForPrelude, hsImportForForeignC]
+        sayLn "HoppyP.flip HoppyFC.withCString stdString_newFromCString"
+      , classHaskellConversionFromCppFn = do
+        addImports $ mconcat [hsImport1 "Control.Monad" "(<=<)", hsImportForForeignC]
+        sayLn "HoppyFC.peekCString <=< stdString_c_str"
+      } $
   makeClass (ident1 "std" "string") (Just $ toExtName "StdString")
   []
   [ mkCtor "new" []
-  , mkCtor "newFromCString" [TPtr $ TConst TChar]
+  , mkCtor "newFromCString" [ptrT $ constT charT]
   ]
-  [ mkConstMethod' "at" "at" [TInt] $ TRef TChar
-  , mkConstMethod' "at" "get" [TInt] TChar
-  , mkConstMethod "c_str" [] $ TPtr $ TConst TChar
-  , mkConstMethod "size" [] TSize
+  [ mkConstMethod' "at" "at" [intT] $ refT charT
+  , mkConstMethod' "at" "get" [intT] charT
+  , mkConstMethod "c_str" [] $ ptrT $ constT charT
+  , mkConstMethod "size" [] sizeT
   ]
diff --git a/src/Foreign/Hoppy/Generator/Std/Vector.hs b/src/Foreign/Hoppy/Generator/Std/Vector.hs
--- a/src/Foreign/Hoppy/Generator/Std/Vector.hs
+++ b/src/Foreign/Hoppy/Generator/Std/Vector.hs
@@ -49,6 +49,7 @@
   )
 import Foreign.Hoppy.Generator.Std (ValueConversion (ConvertPtr, ConvertValue))
 import Foreign.Hoppy.Generator.Std.Iterator
+import Foreign.Hoppy.Generator.Types
 import Foreign.Hoppy.Generator.Version (CppVersion (Cpp2011), activeCppVersion, collect, just, test)
 
 -- | Options for instantiating the vector classes.
@@ -98,50 +99,48 @@
         [ mkCtor "new" []
         ] $
         collect
-        [ just $ mkMethod' "at" "at" [TSize] $ TRef t
-        , just $ mkConstMethod' "at" "atConst" [TSize] $ TRef $ TConst t
-        , just $ mkMethod' "back" "back" [] $ TRef t
-        , just $ mkConstMethod' "back" "backConst" [] $ TRef $ TConst t
-        , just $ mkMethod' "begin" "begin" [] $ TObjToHeap iterator
-        , just $ mkConstMethod' "begin" "beginConst" [] $ TObjToHeap constIterator
-        , just $ mkConstMethod "capacity" [] TSize
-        , just $ mkMethod "clear" [] TVoid
-        , just $ mkConstMethod "empty" [] TBool
-        , just $ mkMethod' "end" "end" [] $ TObjToHeap iterator
-        , just $ mkConstMethod' "end" "endConst" [] $ TObjToHeap constIterator
-        , just $ mkMethod' "erase" "erase" [TObj iterator] TVoid
-        , just $ mkMethod' "erase" "eraseRange" [TObj iterator, TObj iterator] TVoid
-        , just $ mkMethod' "front" "front" [] $ TRef t
-        , just $ mkConstMethod' "front" "frontConst" [] $ TRef $ TConst t
-        , just $ mkMethod' "insert" "insert" [TObj iterator, TRef $ TConst t] TVoid
-        , just $ mkMethod' "insert" "insertAndGetIterator"
-          [TObj iterator, t] $ TObjToHeap iterator
-        , just $ mkConstMethod' "max_size" "maxSize" [] TSize
-        , just $ mkMethod' "pop_back" "popBack" [] TVoid
-        , just $ mkMethod' "push_back" "pushBack" [t] TVoid
-        , just $ mkMethod "reserve" [TSize] TVoid
-        , just $ mkMethod' "resize" "resize" [TSize] TVoid
-        , just $ mkMethod' "resize" "resizeWith" [TSize, t] TVoid
-        , test (activeCppVersion >= Cpp2011) $ mkMethod' "shrink_to_fit" "shrinkToFit" [] TVoid
-        , just $ mkConstMethod "size" [] TSize
-        , just $ mkMethod "swap" [TRef $ TObj vector] TVoid
+        [ just $ mkMethod' "at" "at" [sizeT] $ refT t
+        , just $ mkConstMethod' "at" "atConst" [sizeT] $ refT $ constT t
+        , just $ mkMethod' "back" "back" [] $ refT t
+        , just $ mkConstMethod' "back" "backConst" [] $ refT $ constT t
+        , just $ mkMethod' "begin" "begin" [] $ toGcT $ objT iterator
+        , just $ mkConstMethod' "begin" "beginConst" [] $ toGcT $ objT constIterator
+        , just $ mkConstMethod "capacity" [] sizeT
+        , just $ mkMethod "clear" [] voidT
+        , just $ mkConstMethod "empty" [] boolT
+        , just $ mkMethod' "end" "end" [] $ toGcT $ objT iterator
+        , just $ mkConstMethod' "end" "endConst" [] $ toGcT $ objT constIterator
+        , just $ mkMethod' "erase" "erase" [objT iterator] voidT
+        , just $ mkMethod' "erase" "eraseRange" [objT iterator, objT iterator] voidT
+        , just $ mkMethod' "front" "front" [] $ refT t
+        , just $ mkConstMethod' "front" "frontConst" [] $ refT $ constT t
+        , just $ mkMethod "insert" [objT iterator, t] $ toGcT $ objT iterator
+        , just $ mkConstMethod' "max_size" "maxSize" [] sizeT
+        , just $ mkMethod' "pop_back" "popBack" [] voidT
+        , just $ mkMethod' "push_back" "pushBack" [t] voidT
+        , just $ mkMethod "reserve" [sizeT] voidT
+        , just $ mkMethod' "resize" "resize" [sizeT] voidT
+        , just $ mkMethod' "resize" "resizeWith" [sizeT, t] voidT
+        , test (activeCppVersion >= Cpp2011) $ mkMethod' "shrink_to_fit" "shrinkToFit" [] voidT
+        , just $ mkConstMethod "size" [] sizeT
+        , just $ mkMethod "swap" [refT $ objT vector] voidT
         ]
 
       iterator =
         addReqs reqs $
-        makeRandomIterator Mutable (Just t) TPtrdiff $
+        makeRandomIterator Mutable (Just t) ptrdiffT $
         makeClass (identT' [("std", Nothing), ("vector", Just [t]), ("iterator", Nothing)])
         (Just $ toExtName iteratorName) [] [] []
 
       constIterator =
         addReqs reqs $
-        makeRandomIterator Constant (Just t) TPtrdiff $
+        makeRandomIterator Constant (Just t) ptrdiffT $
         makeClass (identT' [("std", Nothing), ("vector", Just [t]), ("const_iterator", Nothing)])
         (Just $ toExtName constIteratorName) []
-        [ mkCtor "newFromNonconst" [TObj iterator]
+        [ mkCtor "newFromNonconst" [objT iterator]
         ]
         [ makeFnMethod (ident2 "hoppy" "iterator" "deconst") "deconst" MConst Nonpure
-          [TObj constIterator, TRef $ TObj vector] $ TObjToHeap iterator
+          [objT constIterator, refT $ objT vector] $ toGcT $ objT iterator
         ]
 
       -- The addendum for the vector class contains HasContents and FromContents
@@ -158,10 +157,10 @@
           hsValueType <-
             cppTypeToHsTypeAndUse HsHsSide $
             (case conversion of
-               ConvertPtr -> TPtr
+               ConvertPtr -> ptrT
                ConvertValue -> id) $
             case cst of
-              Const -> TConst t
+              Const -> constT t
               Nonconst -> t
 
           -- Generate const and nonconst HasContents instances.
