diff --git a/Data/Strict.hs b/Data/Strict.hs
new file mode 100644
--- /dev/null
+++ b/Data/Strict.hs
@@ -0,0 +1,24 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Strict
+-- Copyright   :  (c) 2006-2007 Roman Leshchinskiy
+-- License     :  BSD-style (see the file LICENSE)
+-- 
+-- Maintainer  :  Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Strict versions of some standard Haskell types.
+--
+-----------------------------------------------------------------------------
+
+module Data.Strict (
+    module Data.Strict.Tuple
+  , module Data.Strict.Maybe
+  , module Data.Strict.Either
+) where
+
+import Data.Strict.Tuple
+import Data.Strict.Maybe
+import Data.Strict.Either
+
diff --git a/Data/Strict/Either.hs b/Data/Strict/Either.hs
new file mode 100644
--- /dev/null
+++ b/Data/Strict/Either.hs
@@ -0,0 +1,64 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Strict.Either
+-- Copyright   :  (c) 2006-2007 Roman Leshchinskiy
+-- License     :  BSD-style (see the file LICENSE)
+-- 
+-- Maintainer  :  Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Strict @Either@.
+--
+-- Same as the standard Haskell @Either@, but @Left _|_ = Right _|_ = _|_@
+--
+-----------------------------------------------------------------------------
+
+module Data.Strict.Either (
+    Either(..)
+  , either
+  , isLeft, isRight
+  , fromLeft, fromRight
+) where
+
+import Prelude hiding( Either(..), either )
+
+-- | The strict choice type.
+data Either a b = Left !a | Right !b deriving(Eq, Ord, Read, Show)
+
+instance Functor (Either a) where
+  fmap _ (Left  x) = Left x
+  fmap f (Right y) = Right (f y)
+
+-- | Case analysis: if the value is @'Left' a@, apply the first function to @a@;
+-- if it is @'Right' b@, apply the second function to @b@.
+either :: (a -> c) -> (b -> c) -> Either a b -> c
+either f _ (Left  x) = f x
+either _ g (Right y) = g y
+
+-- | Yields 'True' iff the argument is of the form @Left _@.
+--
+isLeft :: Either a b -> Bool
+isLeft (Left _) = True
+isLeft _        = False
+
+-- | Yields 'True' iff the argument is of the form @Right _@.
+--
+isRight :: Either a b -> Bool
+isRight (Right _) = True
+isRight _         = False
+
+-- | Extracts the element out of a 'Left' and throws an error if the argument
+-- is a 'Right'.
+fromLeft :: Either a b -> a
+fromLeft (Left x) = x
+fromLeft _        = error "Data.Strict.Either.fromLeft: Right"
+
+-- | Extracts the element out of a 'Right' and throws an error if the argument
+-- is a 'Left'.
+fromRight :: Either a b -> b
+fromRight (Right x) = x
+fromRight _         = error "Data.Strict.Either.fromRight: Left"
+
+
+
diff --git a/Data/Strict/Maybe.hs b/Data/Strict/Maybe.hs
new file mode 100644
--- /dev/null
+++ b/Data/Strict/Maybe.hs
@@ -0,0 +1,68 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Strict.Maybe
+-- Copyright   :  (c) 2006-2007 Roman Leshchinskiy
+-- License     :  BSD-style (see the file LICENSE)
+-- 
+-- Maintainer  :  Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Strict @Maybe@.
+--
+-- Same as the standard Haskell @Maybe@, but @Just _|_ = _|_@
+--
+-- Note that strict @Maybe@ is not a monad since
+-- @ return _|_ >>= f = _|_ @
+-- which is not necessarily the same as @f _|_@.
+--
+-----------------------------------------------------------------------------
+
+module Data.Strict.Maybe (
+    Maybe(..)
+  , isJust
+  , isNothing
+  , fromJust
+  , fromMaybe
+  , maybe
+) where
+
+import Prelude hiding( Maybe(..), maybe )
+
+-- | The type of strict optional values.
+data Maybe a = Nothing | Just !a deriving(Eq, Ord, Show, Read)
+
+instance Functor Maybe where
+  fmap _ Nothing  = Nothing
+  fmap f (Just x) = Just (f x)
+
+-- | Yields 'True' iff the argument is of the form @Just _@.
+isJust :: Maybe a -> Bool
+isJust Nothing = False
+isJust _       = True
+
+-- | Yields 'True' iff the argument is 'Nothing'.
+isNothing :: Maybe a -> Bool
+isNothing Nothing = True
+isNothing _       = False
+
+-- | Extracts the element out of a 'Just' and throws an error if the argument
+-- is 'Nothing'.
+fromJust :: Maybe a -> a
+fromJust Nothing  = error "Data.Strict.Maybe.fromJust: Nothing"
+fromJust (Just x) = x
+
+-- | Given a default value and a 'Maybe', yield the default value if the
+-- 'Maybe' argument is 'Nothing' and extract the value out of the 'Just'
+-- otherwise.
+fromMaybe :: a -> Maybe a -> a
+fromMaybe x Nothing  = x
+fromMaybe _ (Just y) = y
+
+-- | Given a default value, a function and a 'Maybe' value, yields the default
+-- value if the 'Maybe' value is 'Nothing' and applies the function to the
+-- value stored in the 'Just' otherwise.
+maybe :: b -> (a -> b) -> Maybe a -> b
+maybe x _ Nothing  = x
+maybe _ f (Just y) = f y
+
diff --git a/Data/Strict/Tuple.hs b/Data/Strict/Tuple.hs
new file mode 100644
--- /dev/null
+++ b/Data/Strict/Tuple.hs
@@ -0,0 +1,62 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Strict.Tuple
+-- Copyright   :  (c) 2006-2007 Roman Leshchinskiy
+-- License     :  BSD-style (see the file LICENSE)
+-- 
+-- Maintainer  :  Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Strict pairs.
+--
+-- Same as regular Haskell pairs, but @(x :*: _|_) = (_|_ :*: y) = _|_@
+--
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+module Data.Strict.Tuple (
+    Pair(..)
+#ifndef __HADDOCK__
+#ifdef __GLASGOW_HASKELL__
+  , (:!:)
+#endif
+#endif
+  , fst
+  , snd
+  , curry
+  , uncurry
+) where
+
+import Prelude hiding( fst, snd, curry, uncurry )
+import Data.Array (Ix)
+
+infixl 2 :!:
+
+-- | The type of strict pairs.
+data Pair a b = !a :!: !b deriving(Eq, Ord, Show, Read, Bounded, Ix)
+
+#ifndef __HADDOCK__
+#ifdef __GLASGOW_HASKELL__
+-- This gives a nicer syntax for the type but only works in GHC for now.
+type (:!:) = Pair
+#endif
+#endif
+
+-- | Extract the first component of a strict pair.
+fst :: Pair a b -> a
+fst (x :!: _) = x
+
+-- | Extract the second component of a strict pair.
+snd :: Pair a b -> b
+snd (_ :!: y) = y
+
+-- | Curry a function on strict pairs.
+curry :: (Pair a b -> c) -> a -> b -> c
+curry f x y = f (x :!: y)
+
+-- | Convert a curried function to a function on strict pairs.
+uncurry :: (a -> b -> c) -> Pair a b -> c
+uncurry f (x :!: y) = f x y
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) Roman Leshchinskiy 2006-2007
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/strict.cabal b/strict.cabal
new file mode 100644
--- /dev/null
+++ b/strict.cabal
@@ -0,0 +1,22 @@
+Name:           strict
+Version:        0.1
+Synopsis:       Strict data types
+Category:       Data
+Description:
+        This package provides strict versions of some standard Haskell data
+        types (pairs, Maybe and Either at the moment).
+License:        BSD3
+License-File:   LICENSE
+Author:         Roman Leshchinskiy <rl@cse.unsw.edu.au>
+Maintainer:     Roman Leshchinskiy <rl@cse.unsw.edu.au>
+Copyright:      (c) 2006-2007 by Roman Leshchinskiy
+Homepage:       http://www.cse.unsw.edu.au/~rl/code/strict.html
+Exposed-Modules:
+        Data.Strict.Tuple,
+        Data.Strict.Maybe,
+        Data.Strict.Either,
+        Data.Strict
+Build-Depends:  base
+Ghc-Options: -Wall -O
+Extensions:     CPP
+
