diff --git a/src/unify/mod.rs b/src/unify/mod.rs
index defd7b7..604f3bd 100644
--- a/src/unify/mod.rs
+++ b/src/unify/mod.rs
@@ -295,6 +295,12 @@ impl<S: UnificationStoreBase> UnificationTable<S> {
     pub fn len(&self) -> usize {
         self.values.len()
     }
+
+    /// Obtains the current value for a particular key.
+    /// Not for end-users; they can use `probe_value`.
+    fn value(&self, key: S::Key) -> &VarValue<S::Key> {
+        &self.values[key.index() as usize]
+    }
 }
 
 impl<S: UnificationStoreMut> UnificationTable<S> {
@@ -325,12 +331,6 @@ impl<S: UnificationStoreMut> UnificationTable<S> {
         });
     }
 
-    /// Obtains the current value for a particular key.
-    /// Not for end-users; they can use `probe_value`.
-    fn value(&self, key: S::Key) -> &VarValue<S::Key> {
-        &self.values[key.index() as usize]
-    }
-
     /// Find the root node for `vid`. This uses the standard
     /// union-find algorithm with path compression:
     /// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>.
@@ -447,6 +447,28 @@ impl<S: UnificationStoreMut> UnificationTable<S> {
 /// ////////////////////////////////////////////////////////////////////////
 /// Public API
 
+impl<S, K, V> UnificationTable<S>
+where
+    S: UnificationStoreBase<Key = K, Value = V>,
+    K: UnifyKey<Value = V>,
+    V: UnifyValue,
+{
+    /// Obtains current value for key without any pointer chasing; may return `None` if key has been union'd.
+    #[inline]
+    pub fn try_probe_value<'a, K1>(&'a self, id: K1) -> Option<&'a V>
+        where
+            K1: Into<K>,
+            K: 'a,
+    {
+        let id = id.into();
+        let v = self.value(id);
+        if v.parent == id {
+            return Some(&v.value);
+        }
+        None
+    }
+}
+
 impl<S, K, V> UnificationTable<S>
 where
     S: UnificationStoreMut<Key = K, Value = V>,