 mallocHost flags = doMalloc undefined
   where
     doMalloc :: Storable a' => a' -> Int -> IO (HostPtr a')
-    doMalloc x n =
-      newHostPtr >>= \hp -> withHostPtr hp $ \p ->
-      cuMemHostAlloc p (n * sizeOf x) flags >>= nothingIfOk >>
-      return hp
+    doMalloc x n = resultIfOk =<< cuMemHostAlloc (n * sizeOf x) flags
 
 {# fun unsafe cuMemHostAlloc
-  { with'* `Ptr a'
-  ,        `Int'
-  , combineBitMasks `[AllocFlag]' } -> `Status' cToEnum #}
-  where with' = with . castPtr
+  { alloca'-        `HostPtr a'   peekHP*
+  ,                 `Int'
+  , combineBitMasks `[AllocFlag]'         } -> `Status' cToEnum #}
+  where
+    alloca'  = F.alloca
+    peekHP p = (HostPtr . castPtr) `fmap` peek p
 
 
 -- |
 -- Free a section of page-locked host memory
 --
 freeHost :: HostPtr a -> IO ()
-freeHost hp = withHostPtr hp $ \p -> (nothingIfOk =<< cuMemFreeHost p)
+freeHost p = nothingIfOk =<< cuMemFreeHost p
 
 {# fun unsafe cuMemFreeHost
-  { castPtr `Ptr a' } -> `Status' cToEnum #}
+  { useHP `HostPtr a' } -> `Status' cToEnum #}
+  where
+    useHP = castPtr . useHostPtr
+
 
 --------------------------------------------------------------------------------
 -- Device Allocation


-- |
-- Return the device pointer associated with a mapped, pinned host buffer, which
-- was allocated with the DEVICE_MAPPED option.
--
-- Currently, no options are supported and this must be empty.
--
getDevicePtr :: [AllocFlag] -> HostPtr a -> IO (DevicePtr a)
getDevicePtr flags hptr = withHostPtr hptr $ \hp -> (resultIfOk =<< cuMemHostGetDevicePointer hp flags)

{# fun unsafe cuMemHostGetDevicePointer
  { alloca-         `DevicePtr a' dptr*
  , castPtr         `Ptr a'
  , combineBitMasks `[AllocFlag]'       } -> `Status' cToEnum #}
  where dptr = liftM DevicePtr . peek


-- The driver automatically accelerates calls to functions such as `memcpy'
-- which reference page-locked memory.
--
newtype HostPtr a = HostPtr { useHostPtr :: Ptr a }

-- |
-- Unwrap a host pointer and execute a computation using the base pointer object
--
withHostPtr :: HostPtr a -> (Ptr a -> IO b) -> IO b
withHostPtr p f = f (useHostPtr p)

-- |
-- Options for host allocation
