diff --git a/prim.cabal b/prim.cabal
--- a/prim.cabal
+++ b/prim.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.4
 name: prim
 homepage: https://github.com/daig/prim#readme
-version: 0.1.0.6
+version: 0.1.0.7
 category: Prelude
 synopsis: An ergonomic but conservative interface to ghc-prim
 description: 
@@ -31,6 +31,7 @@
   default-extensions: MagicHash, UnboxedTuples
                     , KindSignatures, PolyKinds, ConstraintKinds, TypeOperators, RankNTypes
                     , BlockArguments
+                    , PatternSynonyms, ViewPatterns
   hs-source-dirs: src
   other-modules: Prelude
   exposed-modules: Char
@@ -69,7 +70,8 @@
                  , RTS.Prefetch.Any, RTS.Prefetch.Ref, RTS.Prefetch.Array, RTS.Prefetch.Array.M
                  , String, String.C, String.C.Latin, String.C.UTF8, String.List
                  , Nat
-                 , Stock
+                 , Stock.Eq, Stock.Ord, Stock.Ord.Ordering
+                 , Stock.B, Stock.Char, Stock.Double, Stock.Float, Stock.Int, Stock.Word, Stock.IO
                  , Syntax.ImplicitParam
                  , Prim
   build-depends: ghc-prim ^>= 0.6.1
diff --git a/src/Enum.hs b/src/Enum.hs
--- a/src/Enum.hs
+++ b/src/Enum.hs
@@ -1,10 +1,27 @@
-{-# language ScopedTypeVariables, RankNTypes, TypeApplications #-}
+{-# language BangPatterns, ScopedTypeVariables, RankNTypes, TypeApplications #-}
 module Enum
   (-- | Must be evaluated, not a thunk
    dataToTag# 
   -- | @a@ must be an enum type
   ,tagToEnum#
+  ,toI64
   ) where
 
 -- Note we can't fiddle with tagToEnum# eg to rename
 -- because of ghc magic prefenting it used at higher order
+
+
+{- |
+Returns the 'tag' of a constructor application; this function is used
+by the deriving code for Eq, Ord and Enum.
+
+The primitive dataToTag# requires an evaluated constructor application
+as its argument, so we provide getTag as a wrapper that performs the
+evaluation before calling dataToTag#.  We could have dataToTag#
+evaluate its argument, but we prefer to do it this way because (a)
+dataToTag# can be an inline primop if it doesn't need to do any
+evaluation, and (b) we want to expose the evaluation to the
+simplifier, because it might be possible to eliminate the evaluation
+in the case when the argument is already known to be evaluated. -}
+toI64 :: a -> I64; {-# inline toI64 #-}
+toI64 !x = dataToTag# x
diff --git a/src/I64.hs b/src/I64.hs
--- a/src/I64.hs
+++ b/src/I64.hs
@@ -1,5 +1,7 @@
+{-# language BangPatterns #-}
 module I64 (I64, module I64) where
-import qualified GHC.Types 
+import Stock.B (pattern B#)
+import qualified GHC.Classes as GHC (divInt#,modInt#)
 
 add,sub,mul, quot, rem :: I64 -> I64 -> I64
 add y x = x +# y
@@ -38,6 +40,12 @@
 -- | Rounds towards zero
 quotRem y x = quotRemInt# x y
 
+-- These functions have built-in rules.
+div,mod :: I64 {- ^ divisor -} -> I64 {- ^ dividend -} -> I64 {- ^ modulus -}
+div y x = GHC.divInt# x y; {-# inline div #-}
+mod y x = GHC.modInt# x y; {-# inline mod #-}
+
+
 addC, subC :: I64 -> I64 -> (# I64, B #)
 -- |Add signed integers reporting overflow.
 --           First member of result is the sum truncated to an @I64@;
@@ -76,8 +84,6 @@
 toI16 = narrow16Int#
 toI32 :: I64 -> I32
 toI32 = narrow32Int#
-
-
 
 -- |Shift right arithmetic.  Result undefined if shift amount is not
 --           in the range 0 to word size - 1 inclusive.
diff --git a/src/Stock.hs b/src/Stock.hs
deleted file mode 100644
--- a/src/Stock.hs
+++ /dev/null
@@ -1,4 +0,0 @@
-{-| Description : Stock datatypes and classes -}
-module Stock (module X) where
-import GHC.Types as X (Bool(..),Char(..),Int(..),Word(..),Float(..),Double(..),IO(..),Ordering(..))
-import GHC.Classes as X (Eq(..),Ord(..),(&&),(||),not)
diff --git a/src/Stock/B.hs b/src/Stock/B.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/B.hs
@@ -0,0 +1,18 @@
+module Stock.B (module Stock.B, module X) where
+import qualified Prelude as Prim
+import GHC.Types (Bool(..),isTrue#)
+import GHC.Classes as X ((&&),(||),not)
+
+type B = Bool
+pattern O :: B
+pattern O = False
+pattern I :: B
+pattern I = True
+{-# complete O,I #-}
+
+pattern B# :: Prim.B -> B
+pattern B# i <- (Prim.dataToTag# -> i) where B# i = isTrue# i
+
+and, or :: B -> B -> B
+and = (&&); {-# inline and #-}
+or = (||); {-# inline or #-}
diff --git a/src/Stock/Char.hs b/src/Stock/Char.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Char.hs
@@ -0,0 +1,2 @@
+module Stock.Char (module X) where
+import GHC.Types as X (Char(..))
diff --git a/src/Stock/Double.hs b/src/Stock/Double.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Double.hs
@@ -0,0 +1,2 @@
+module Stock.Double (module X) where
+import GHC.Types as X (Double(..))
diff --git a/src/Stock/Eq.hs b/src/Stock/Eq.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Eq.hs
@@ -0,0 +1,2 @@
+module Stock.Eq (module X) where
+import GHC.Classes as X (Eq(..))
diff --git a/src/Stock/Float.hs b/src/Stock/Float.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Float.hs
@@ -0,0 +1,2 @@
+module Stock.Float (module X) where
+import GHC.Types as X (Float(..))
diff --git a/src/Stock/IO.hs b/src/Stock/IO.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/IO.hs
@@ -0,0 +1,2 @@
+module Stock.IO (module X) where
+import GHC.Types as X (IO(..))
diff --git a/src/Stock/Int.hs b/src/Stock/Int.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Int.hs
@@ -0,0 +1,3 @@
+module Stock.Int (module X) where
+
+import GHC.Types as X (Int(..))
diff --git a/src/Stock/Ord.hs b/src/Stock/Ord.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Ord.hs
@@ -0,0 +1,3 @@
+module Stock.Ord (module X) where
+import GHC.Classes as X (Ord(..))
+import Stock.Ord.Ordering as X
diff --git a/src/Stock/Ord/Ordering.hs b/src/Stock/Ord/Ordering.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Ord/Ordering.hs
@@ -0,0 +1,2 @@
+module Stock.Ord.Ordering where
+import GHC.Types as X (Ordering(..))
diff --git a/src/Stock/Word.hs b/src/Stock/Word.hs
new file mode 100644
--- /dev/null
+++ b/src/Stock/Word.hs
@@ -0,0 +1,2 @@
+module Stock.Word (module X) where
+import GHC.Types as X (Word(..))
