diff --git a/lub.cabal b/lub.cabal
--- a/lub.cabal
+++ b/lub.cabal
@@ -1,7 +1,7 @@
 Name:                lub
-Version:             0.0.6
+Version:             0.1.1
 Cabal-Version:       >= 1.2
-Synopsis:            least upper bounds -- information merging
+Synopsis:            information operators: least upper bound (lub) and greatest lower bound (glb)
 Category:            Concurrency, Data, Other
 Description:
   Lub is an experiment in computing least upper information bounds on
@@ -11,6 +11,8 @@
   neither is bottom, 'lub' is able to synthesize a value from the
   partial information contained in both of its arguments.
   .
+  This module also defines 'glb', which intersects information.
+  .
   Project wiki page: <http://haskell.org/haskellwiki/lub>
   .
   &#169; 2008 by Conal Elliott; BSD3 license.
@@ -26,10 +28,12 @@
 Library
   hs-Source-Dirs:      src
   Extensions:
-  Build-Depends:       base < 5, unamb >= 0.1.3
+  Build-Depends:       base < 5, unamb >= 0.2.4
   Exposed-Modules:     
                        Data.Repr
                        Data.Lub
+                       Data.Glb
+                       Data.Lazier
                        
   ghc-options:         -Wall
 
diff --git a/src/Data/Glb.hs b/src/Data/Glb.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Glb.hs
@@ -0,0 +1,92 @@
+-- {-# LANGUAGE #-}
+{-# OPTIONS_GHC -Wall #-}
+----------------------------------------------------------------------
+-- |
+-- Module      :  Data.Glb
+-- Copyright   :  (c) Conal Elliott 2010
+-- License     :  BSD3
+-- 
+-- Maintainer  :  conal@conal.net
+-- Stability   :  experimental
+-- 
+-- Greatest lower bound
+----------------------------------------------------------------------
+
+module Data.Glb (HasGlb(..),glbBottom,flatGlb) where
+
+import Control.Applicative (liftA2)
+
+import Data.Repr
+
+-- | Types that support information intersection ('glb')
+class HasGlb a where
+  -- | Greatest lower information bound.  Intersects information available
+  -- from each argument.
+  glb  :: a -> a -> a
+  -- | n-ary 'lub'.  Defaults to @foldr lub undefined@
+  glbs :: [a] -> a
+  glbs = foldr glb undefined
+
+-- | Bottom for a 'glb'.  In the form of @error \"glb: bottom (\<reason\>)\"@,
+-- though not really an error.
+glbBottom :: String -> a
+glbBottom msg = error $ "glb: bottom (" ++ msg ++ ")"
+
+-- | 'glb' on flat types with equality.  Gives bottom for unequal
+-- arguments.
+flatGlb :: Eq a => a -> a -> a
+flatGlb a b | a == b    = a
+            | otherwise = glbBottom "flat & unequal"
+
+-- Flat types:
+instance HasGlb ()      where glb = flatGlb
+instance HasGlb Bool    where glb = flatGlb
+instance HasGlb Char    where glb = flatGlb
+instance HasGlb Int     where glb = flatGlb
+instance HasGlb Integer where glb = flatGlb
+instance HasGlb Float   where glb = flatGlb
+instance HasGlb Double  where glb = flatGlb
+-- ...
+
+instance (HasGlb a, HasGlb b) => HasGlb (a,b) where
+  (a,b) `glb` (a',b') = (a `glb` a', b `glb` b')
+
+instance HasGlb b => HasGlb (a -> b) where
+  glb = liftA2 glb
+
+instance (HasGlb a, HasGlb b) => HasGlb (Either a b) where
+  Left  a `glb` Left  a' = Left  (a `glb` a')
+  Right b `glb` Right b' = Right (b `glb` b')
+  _ `glb` _ = glbBottom "glb: bottom (Left/Right mismatch)"
+
+
+-- 'glb' on representations
+repGlb :: (HasRepr a v, HasGlb v) => a -> a -> a
+repGlb = onRepr2 glb
+
+-- instance (HasRepr t v, HasGlb v) => HasGlb t where
+--   glb = repGlb
+
+-- For instance,
+instance HasGlb a => HasGlb (Maybe a) where glb = repGlb
+instance HasGlb a => HasGlb [a]       where glb = repGlb
+
+{- -- Examples
+
+-- It takes care to check that some of these examples are computed
+-- correctly, since printing stops at the first error.  For instance, ask
+-- for t5!!1 .
+
+t1,t2 :: Int
+t1 = 6 `glb` 8  -- _|_
+t2 = 7 `glb` 7  -- 7
+
+t3,t4 :: (Int,Int)
+t3 = (3,4) `glb` (4,5)  -- (_|_,_|_)
+t4 = (3,4) `glb` (3,5)  -- (3,_|_)
+
+t5 :: [Int]
+t5 = [2,3,5] `glb` [1,3]  -- _|_:3:_|_
+
+-}
+
diff --git a/src/Data/Lazier.hs b/src/Data/Lazier.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Lazier.hs
@@ -0,0 +1,67 @@
+-- {-# LANGUAGE #-}
+{-# OPTIONS_GHC -Wall #-}
+----------------------------------------------------------------------
+-- |
+-- Module      :  Data.Lazier
+-- Copyright   :  (c) Conal Elliott 2010
+-- License     :  BSD3
+-- 
+-- Maintainer  :  conal@conal.net
+-- Stability   :  experimental
+-- 
+-- Some lazier operations.
+-- See <http://conal.net/blog/posts/lazier-functional-programming-part-2/>
+----------------------------------------------------------------------
+
+module Data.Lazier (eitherL,condL) where
+
+import Data.Lub
+import Data.Glb
+
+condL :: (HasLub a, HasGlb a) =>
+         a -> a -> Bool -> a
+condL a b = const (a `glb` b) `lub` (\ c -> if c then a else b)
+
+eitherL :: (HasLub c, HasGlb c) =>
+           (a -> c) -> (b -> c) -> (Either a b -> c)
+eitherL f g = const (f undefined `glb` g undefined) `lub` either f g
+
+{- -- Examples:
+
+-- It takes care to check that some of these examples are computed
+-- correctly, since printing stops at the first error.  For instance, ask
+-- for t5!!1 .
+
+q :: Int
+q = undefined `unamb` 5
+
+t0 :: Int
+t0 = condL 3 4 True
+
+t1,t2 :: Int
+t1 = condL 6 8 undefined  -- _|_
+t2 = condL 7 7 undefined  -- 7
+
+t3,t4 :: (Int,Int)
+t3 = condL (3,4) (4,5) undefined  -- (_|_,_|_)
+t4 = condL (3,4) (3,5) undefined  -- (3,_|_)
+
+t5 :: [Int]
+t5 = condL [2,3,5] [1,3] undefined  -- _|_:3:_|_
+
+
+fe1 :: Either Float Bool -> (Int,String)
+fe1 = eitherL (\ x -> (3,"beetle " ++ show x)) (\ b -> (3,"battle " ++ show b))
+
+s1 :: (Int,String)
+s1 = fe1 undefined
+-- (3,"b*** Exception: glb: bottom (flat & unequal)
+
+s2 :: String
+s2 = (tail.tail.tail.snd) (fe1 undefined)
+-- "tle *** Exception: Prelude.undefined
+
+s3 :: (Int,String)
+s3 = fe1 (Left pi)
+
+-}
