diff --git a/Boolean.cabal b/Boolean.cabal
--- a/Boolean.cabal
+++ b/Boolean.cabal
@@ -1,20 +1,26 @@
 Name:                Boolean
-Version:             0.0.1
-Cabal-Version:       >= 1.2
+Version:             0.1.0
+Cabal-Version:       >= 1.6
 Synopsis:            Generalized booleans
 Category:            Data
 Description:
   Some classes for generalized boolean operations.
+  Starting with 0.1.0, this package uses type families.
+  Up to version 0.0.2, it used MPTCs with functional dependencies.
+  My thanks to Andy Gill for suggesting & helping with the change.
   .
-  Copyright 2009 Conal Elliott; BSD3 license.
+  Copyright 2009-2012 Conal Elliott; BSD3 license.
 Author:              Conal Elliott
 Maintainer:          conal@conal.net
-Package-Url:         http://code.haskell.org/~conal/code/Boolean
-Copyright:           (c) 2009 by Conal Elliott
+Copyright:           (c) 2009-2012 by Conal Elliott
 License:             BSD3
 License-File:        COPYING
 Stability:           experimental
 build-type:          Simple
+
+source-repository head
+  type:     git
+  location: git://github.com/conal/Boolean.git
 
 Library
   hs-Source-Dirs:      src
diff --git a/COPYING b/COPYING
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2009 Conal Elliott
+Copyright (c) 2009-2012 Conal Elliott
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/Makefile b/Makefile
deleted file mode 100644
--- a/Makefile
+++ /dev/null
@@ -1,1 +0,0 @@
-include ../cho-home-cabal-make.inc
diff --git a/src/Data/Boolean.hs b/src/Data/Boolean.hs
--- a/src/Data/Boolean.hs
+++ b/src/Data/Boolean.hs
@@ -1,11 +1,16 @@
 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies
            , UndecidableInstances, ScopedTypeVariables
   #-}
+{-# LANGUAGE TypeFamilies, FlexibleContexts, CPP #-}
 {-# OPTIONS_GHC -Wall #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-imports #-} -- TEMP
+{-# OPTIONS_GHC -fno-warn-unused-binds   #-} -- TEMP
+
 ----------------------------------------------------------------------
 -- |
 -- Module      :  Data.Boolean
--- Copyright   :  (c) Conal Elliott 2009
+-- Copyright   :  (c) Conal Elliott 2009-2012
 -- License     :  BSD3
 -- 
 -- Maintainer  :  conal@conal.net
@@ -14,21 +19,24 @@
 -- Some classes for generalized boolean operations.
 -- 
 -- In this design, for if-then-else, equality and inequality tests, the
--- boolean type depends functionally on the value type.  This dependency
--- allows the boolean type to be inferred in a conditional expression.
+-- boolean type depends on the value type.
 -- 
 -- I also tried using a unary type constructor class.  The class doesn't work
 -- for regular booleans, so generality is lost.  Also, we'd probably have
 -- to wire class constraints in like: @(==*) :: Eq a => f Bool -> f a -> f
 -- a -> f a@, which disallows situations needing additional constraints,
 -- e.g., Show.
--- 
+--
+-- Starting with 0.1.0, this package uses type families.
+-- Up to version 0.0.2, it used MPTCs with functional dependencies.
+-- My thanks to Andy Gill for suggesting & helping with the change.
+
 ----------------------------------------------------------------------
 
 module Data.Boolean
   (
-    Boolean(..),IfB(..), boolean, cond, crop
-  , EqB(..), OrdB(..), minB, maxB
+    Boolean(..), BooleanOf, IfB(..), boolean, cond, crop
+  , EqB(..), OrdB(..), minB, maxB, sort2B
   ) where
 
 import Data.Monoid (Monoid,mempty)
@@ -55,85 +63,121 @@
   (&&*) = (&&)
   (||*) = (||)
 
+-- | 'BooleanOf' computed the boolean analog of a specific type.
+type family BooleanOf a
+
 -- | Types with conditionals
-class Boolean bool => IfB bool a | a -> bool where
-  ifB  :: bool -> a -> a -> a
+class Boolean (BooleanOf a) => IfB a where
+  ifB  :: (bool ~ BooleanOf a) => bool -> a -> a -> a
 
 -- | Expression-lifted conditional with condition last
-boolean :: IfB bool a => a -> a -> bool -> a
+boolean :: (IfB a, bool ~ BooleanOf a) => a -> a -> bool -> a
 boolean t e bool = ifB bool t e
 
 -- | Point-wise conditional
-cond :: (Applicative f, IfB bool a) => f bool -> f a -> f a -> f a
+cond :: (Applicative f, IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a -> f a
 cond = liftA3 ifB
 
--- | Crop a function, filling in 'mempty' where the test yeis false.
-crop :: (Applicative f, Monoid (f a), IfB bool a) => f bool -> f a -> f a
+-- | Generalized cropping, filling in 'mempty' where the test yields false.
+crop :: (Applicative f, Monoid (f a), IfB a, bool ~ BooleanOf a) => f bool -> f a -> f a
 crop r f = cond r f mempty
 
-
 infix  4  ==*, /=*
 
 -- | Types with equality.  Minimum definition: '(==*)'.
-class Boolean bool => EqB bool a | a -> bool where
-  (==*), (/=*) :: a -> a -> bool
+class Boolean (BooleanOf a) => EqB a where
+  (==*), (/=*) :: (bool ~ BooleanOf a) => a -> a -> bool
   u /=* v = notB (u ==* v)
 
 infix  4  <*, <=*, >=*, >*
 
 -- | Types with inequality.  Minimum definition: '(<*)'.
-class Boolean bool => OrdB bool a | a -> bool where
-  (<*), (<=*), (>*), (>=*) :: a -> a -> bool
+class Boolean (BooleanOf a) => OrdB a where
+  (<*), (<=*), (>*), (>=*) :: (bool ~ BooleanOf a) => a -> a -> bool
   u >*  v = v <* u
   u >=* v = notB (u <* v)
   u <=* v = v >=* u
 
 -- | Variant of 'min' using 'ifB' and '(<=*)'
-minB :: (IfB bool a, OrdB bool a) => a -> a -> a
+minB :: (IfB a, OrdB a) => a -> a -> a
 u `minB` v = ifB (u <=* v) u v
 
 -- | Variant of 'max' using 'ifB' and '(>=*)'
-maxB :: (IfB bool a, OrdB bool a) => a -> a -> a
+maxB :: (IfB a, OrdB a) => a -> a -> a
 u `maxB` v = ifB (u >=* v) u v
 
+-- | Variant of 'min' using 'ifB' and '(<=*)'
+sort2B :: (IfB a, OrdB a) => (a,a) -> (a,a)
+sort2B (u,v) = ifB (u <=* v) (u,v) (v,u)
+
 {--------------------------------------------------------------------
-    Some instances
+    Instances for Prelude types
 --------------------------------------------------------------------}
 
+-- Simple if-then-else as function.
 ife :: Bool -> a -> a -> a
 ife c t e = if c then t else e
 
 -- I'd give the following instances:
 -- 
---     instance IfB  Bool a where ifB = ife
---     instance EqB  Bool a where { (==*) = (==) ; (/=*) = (/=) }
---     instance OrdB Bool a where { (<*) = (<) ; (<=*) = (<=)}
+--     instance          IfB a where ifB = ife
+--     instance Eq  a => EqB a where { (==*) = (==) ; (/=*) = (/=) }
+--     instance Ord a => Ord a where { (<*) = (<) ; (<=*) = (<=)}
 -- 
 -- Sadly, doing so would break the a->bool fundep, which is needed elsewhere
 -- for disambiguation.  So use the instances above as templates, filling
 -- in specific types for a.
 
+#define SimpleInstances(Ty) \
+instance IfB  (Ty) where { ifB = ife } ;\
+instance EqB  (Ty) where { (==*) = (==) ; (/=*) = (/=) } ;\
+instance OrdB (Ty) where { (<*) = (<) ; (<=*) = (<=) }
 
-instance IfB  Bool Float where ifB = ife
-instance EqB  Bool Float where { (==*) = (==) ; (/=*) = (/=) }
-instance OrdB Bool Float where { (<*) = (<) ; (<=*) = (<=) }
+#define SimpleTy(Ty) \
+type instance BooleanOf (Ty) = Bool ;\
+SimpleInstances(Ty)
 
--- Similarly for other types.  
+SimpleTy(Int)
+SimpleTy(Integer)
+SimpleTy(Float)
+SimpleTy(Double)
+SimpleTy(Bool)
+SimpleTy(Char)
 
+-- Similarly for other simple types.
 
-instance (IfB bool p, IfB bool q) => IfB bool (p,q) where
+-- TODO: Export these macros for external use. I guess I'd want a .h file as in
+-- the applicative-numbers package.
+
+type instance BooleanOf [a]       = BooleanOf a
+type instance BooleanOf (a,b)     = BooleanOf a
+type instance BooleanOf (a,b,c)   = BooleanOf a
+type instance BooleanOf (a,b,c,d) = BooleanOf a
+type instance BooleanOf (z -> a)  = z -> BooleanOf a
+
+-- I'm uncomfortable with this list instance. It's unlike tuples and unlike
+-- functions. It could be generalized from BooleanOf a ~ Bool to a general case
+-- for applicatives, but then the list version would form cross products.
+-- Consider strings and other list types under a variety of use scenarios.
+
+instance (Boolean (BooleanOf a),BooleanOf a ~ Bool) => IfB [a] where { ifB = ife }
+
+instance (bool ~ BooleanOf p, bool ~ BooleanOf q
+         ,IfB p, IfB q) => IfB (p,q) where
   ifB w (p,q) (p',q') = (ifB w p p', ifB w q q')
 
-instance (IfB bool p, IfB bool q, IfB bool r) => IfB bool (p,q,r) where
+instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r
+         ,IfB p, IfB q, IfB r)
+      => IfB (p,q,r) where
   ifB w (p,q,r) (p',q',r') = (ifB w p p', ifB w q q', ifB w r r')
 
-instance (IfB bool p, IfB bool q, IfB bool r, IfB bool s) => IfB bool (p,q,r,s) where
+instance (bool ~ BooleanOf p, bool ~ BooleanOf q, bool ~ BooleanOf r, bool ~ BooleanOf s
+         ,IfB p, IfB q, IfB r, IfB s) => IfB (p,q,r,s) where
   ifB w (p,q,r,s) (p',q',r',s') =
     (ifB w p p', ifB w q q', ifB w r r', ifB w s s')
 
-
-
--- Standard pattern for applicative functors:
+-- Instances for functions, using the standard pattern for applicative functions.
+-- Note that the [] applicative does not use this instance. Fishy.
 
 instance Boolean bool => Boolean (z -> bool) where
   true  = pure true
@@ -142,14 +186,16 @@
   (&&*) = liftA2 (&&*)
   (||*) = liftA2 (||*)
 
-instance IfB bool a => IfB (z -> bool) (z -> a) where
+instance IfB a => IfB (z -> a) where
   ifB = cond
 
-instance EqB  bool a => EqB  (z -> bool) (z -> a) where
+instance EqB a => EqB (z -> a) where
   { (==*) = liftA2 (==*) ; (/=*) = liftA2 (/=*) }
-instance OrdB bool a => OrdB (z -> bool) (z -> a) where
-  { (<*) = liftA2(<*) ; (<=*) = liftA2(<=*) }
+instance OrdB a => OrdB (z -> a) where
+  { (<*) = liftA2 (<*) ; (<=*) = liftA2 (<=*) }
 
+-- TODO: Generalize the function instance into a macro for arbitrary
+-- applicatives. Instantiate for functions.
 
 {-
 
