thName :: Lua.StackIndex
              -> String         -- ^ expected metatable name
              -> Lua (Maybe a)
toAnyWithName idx name = do
  l <- Lua.state
  udPtr <- Lua.liftIO (C.withCString name (luaL_testudata l idx))
  if udPtr == Ptr.nullPtr
    then return Nothing
    else
      fmap Just . Lua.liftIO $
      Storable.peek (Ptr.castPtr udPtr) >>= StablePtr.deRefStablePtr

-- | Retrieve Haskell data which was pushed to Lua as userdata.
peekAn
toAnyWithName :: Lua.StackIndex
              -> String         -- ^ expected metatable name
              -> Lua (Maybe a)
toAnyWithName idx name = do
  l <- Lua.state
  udPtr <- Lua.liftIO (C.withCString name (luaL_testudata l idx))
  if udPtr == Ptr.nullPtr
    then return Nothing
    else
      fmap Just . Lua.liftIO $
      Storable.peek (Ptr.castPtr udPtr) >>= StablePtr.deRefStablePtr

-- | Retrieve Haskell data which was pushed to Lua as userdata.
toAnyWithName idx name = do
  l <- Lua.state
  udPtr <- Lua.liftIO (C.withCString name (luaL_testudata l idx))
  if udPtr == Ptr.nullPtr
    then return Nothing
    else
      fmap Just . Lua.liftIO $
      Storable.peek (Ptr.castPtr udPtr) >>= StablePtr.deRefStablePtr

-- | Retrieve Haskell data which was pushed to Lua as userdata.