diff --git a/hx.cabal b/hx.cabal
--- a/hx.cabal
+++ b/hx.cabal
@@ -1,5 +1,5 @@
 Name:           hx
-Version:        0.3
+Version:        0.4
 Synopsis:       Haskell extras (missing utility functions).
 Description:    Utility functions that some may feel are missing from Prelude and base.
                 .
@@ -20,8 +20,9 @@
     Exposed-Modules:    Haskell.X
                         , Haskell.X.Ops
                         , Haskell.X.Unsafe
+                        , Haskell.X.Prelude
 
-    Build-Depends:      base >= 4 && < 5
+    Build-Depends:      base >= 4.5 && < 5
     Hs-Source-Dirs:     src
 
 
diff --git a/src/Haskell/X.hs b/src/Haskell/X.hs
--- a/src/Haskell/X.hs
+++ b/src/Haskell/X.hs
@@ -14,6 +14,7 @@
 module Haskell.X where
 
 import Prelude
+import Data.Char
 import Data.List
 import Data.Ord
 import Control.Arrow
@@ -118,5 +119,47 @@
 -- unify it by dropping the Either wrapper.
 uneither :: Either a a -> a
 uneither = either id id
+
+
+data Version = Version {
+    versionBranch :: [Integer],
+    versionTags :: [String]
+  } deriving (Eq, Ord)
+
+instance Read Version where
+    readsPrec _ = parseVersion
+
+instance Show Version where
+    showsPrec _ (Version branch tags) xs
+      = tail (concatMap (('.':) . show) branch) ++ concatMap ('-':) tags ++ xs
+
+parseVersion :: String -> [(Version, String)]
+parseVersion string =
+    let (digits, tagRest) = parseBranch string
+        (tags, rest) = parseTags tagRest
+    in if null digits then [] else [(Version (map read digits) tags, rest)]
+  where
+    parseBranch str =
+        let next = span isDigit str
+        in case next of
+            ("", rest) -> ([], rest)
+            (ds, '.':rest) -> let (dss, rest') = parseBranch rest
+                              in  (ds : dss, rest')
+            (ds, rest) -> ([ds], rest)
+
+    parseTags ('-':str) =
+        let next = span isAlphaNum str
+        in case next of
+            ("", rest) -> ([], rest)
+            (xs, rest) -> let (xss, rest') = parseTags rest
+                              in  (xs : xss, rest')
+    parseTags xs = ([], xs)
+
+
+
+
+
+
+
 
 
diff --git a/src/Haskell/X/Prelude.hs b/src/Haskell/X/Prelude.hs
new file mode 100644
--- /dev/null
+++ b/src/Haskell/X/Prelude.hs
@@ -0,0 +1,297 @@
+{-# LANGUAGE Haskell2010, Safe, TypeFamilies #-}
+-- {-# OPTIONS -Wall #-}
+
+module Haskell.X.Prelude (
+    
+    Bool (True, False), (&&), (||), not, otherwise,
+
+    Maybe (Nothing, Just), maybe, isJust, isNothing,
+    fromJust, fromMaybe, listToMaybe, maybeToList, catMaybes,
+    mapMaybe,
+
+    Either (Left, Right), either, lefts, rights,
+    partitionEithers, uneither,
+
+    Ordering (LT, EQ, GT),
+
+    Char,
+    isControl, isSpace, isLower, isUpper, isAlpha, isAlphaNum,
+    isPrint, isDigit, isOctDigit, isHexDigit, isLetter, isMark,
+    isNumber, isPunctuation, isSymbol, isSeparator,
+    isAscii, isLatin1, isAsciiUpper, isAsciiLower,
+
+    IsString (fromString),
+
+    toUpper, toLower, toTitle,
+    digitToInt, intToDigit, ord, chr,
+
+    AtLeastPair (..),
+    curry, uncurry, swap,
+
+    Eq ((==), (/=)),
+    Ord (compare, (<), (>=), (>), (<=), max, min),
+    Enum (succ, pred, toEnum, fromEnum, enumFrom, enumFromThen, enumFromTo, enumFromThenTo),
+    Bounded (minBound, maxBound),
+
+    Int, Integer, Float, Double,
+    Int8, Int16, Int32, Int64,
+    Word8, Word16, Word32, Word64,
+
+    Rational, Ratio,
+
+    Num (
+        (+), (*), (-), negate, abs, signum, fromInteger
+    ),
+    Real (toRational),
+    Integral (
+        quot, rem, div, mod, quotRem, divMod, toInteger
+    ),
+    Fractional (
+        (/), recip, fromRational
+    ),
+    Floating (
+        pi, exp, sqrt, log, (**), logBase,
+        sin, tan, cos, asin, atan, acos,
+        sinh, tanh, cosh, asinh, atanh, acosh
+    ),
+    RealFrac (
+        properFraction, truncate, round, ceiling, floor
+    ),
+    RealFloat (
+        floatRadix, floatDigits, floatRange,
+        decodeFloat, encodeFloat, exponent, significand,
+        scaleFloat, isNaN, isInfinite, isDenormalized,
+        isNegativeZero, isIEEE, atan2
+    ),
+
+    Complex, realPart, imagPart, mkPolar, cis, polar,
+    magnitude, phase, conjugate,
+
+    subtract, even, odd, gcd, lcm, (^), (^^),
+    fromIntegral, realToFrac,
+
+    Functor (fmap, (<$)),
+    id, const, (.), flip, ($), fix, on,
+    until, asTypeOf, error, undefined, seq, ($!),
+
+    Applicative (pure, (<*>), (*>), (<*)),
+
+    Monad ((>>=), (>>), return, fail), (=<<), (>=>), (<=<),
+    forever, void, join,
+
+    MonadPlus (mzero, mplus),
+    mapM, mapM_, forM, forM_, sequence, sequence_,
+    msum, mfilter, filterM,
+    mapAndUnzipM, zipWithM, zipWithM_,
+    foldM, foldM_,
+    replicateM, replicateM_,
+    guard, when, unless,
+    liftM, liftM2, liftM3, liftM4, liftM5,
+    ap,
+
+    Monoid (mempty, mappend, mconcat),
+    (<>),
+    Dual (..), Endo (..),
+    All (..), Any (..),
+    Sum (..), Product (..),
+    First (..), Last (..),
+
+    Alternative ((<|>), empty, some, many),
+
+    Const (..),
+    WrappedMonad (..),
+    WrappedArrow (..),
+    ZipList (..),
+
+    (<$>), (<**>), liftA, liftA2, liftA3, optional,
+
+    Arrow (arr, first, second, (***), (&&&)),
+    Kleisli (..),
+    returnA, (^>>), (>>^), (>>>), (<<<),
+    (<<^), (^<<),
+    ArrowZero (zeroArrow),
+    ArrowPlus ((<+>)),
+    ArrowChoice (left, right, (+++), (|||)),
+    ArrowApply (app),
+    ArrowMonad (..),
+    leftApp,
+
+    ArrowLoop (loop),
+
+    map, (++), (!!), reverse,
+    filter, head, last, tail, init, null, length,
+
+    Traversable (traverse, sequenceA),
+
+    Foldable (fold, foldMap, foldr, foldl, foldr1, foldl1),
+    foldrM, foldlM, traverse_, for_, sequenceA_, asum,
+    foldl', foldr', toList, find,
+
+    and, or, any, all, sum, product, concat, concatMap,
+    maximum, minimum,
+
+    scanl, scanl1, scanr, scanr1,
+
+    iterate, repeat, replicate, cycle,
+    take, drop, splitAt, takeWhile, dropWhile,
+    span, break,
+
+    elem, notElem, lookup,
+
+    intersperse, intercalate, transpose, subsequences, permutations,
+    mapAccumL, mapAccumR, unfoldr,
+
+    stripPrefix, group, inits, tails, isPrefixOf, isSuffixOf, isInfixOf,
+    partition, elemIndex, elemIndices, findIndex, findIndices,
+
+    zip, zip3, zip4, zip5, zip6, zip7,
+    zipWith, zipWith3, zipWith4, zipWith5, zipWith6, zipWith7,
+    unzip, unzip3, unzip4, unzip5, unzip6, unzip7,
+
+    nub, delete, union, intersect, sort, insert,
+    nubBy, deleteBy, deleteFirstsBy, unionBy, intersectBy, groupBy,
+    sortBy, insertBy, maximumBy, minimumBy,
+
+    lines, words, unlines, unwords,
+
+    ShowS, Show (..), shows, showChar, showString, showParen,
+    ReadS, Read (..), reads, readParen, read, lex,
+
+    IO,
+
+    putChar, putStr, putStrLn, print,
+    getChar, getLine, getContents, interact,
+
+    readFile, writeFile, appendFile,
+    readIO, readLn,
+
+    (->>),
+
+    SomeException, Exception (toException, fromException),
+
+    IOException, ioError, userError,
+    throw, throwIO, throwTo,
+    catch, catches,
+
+    Handler (Handler),
+
+    catchJust,
+    handle, handleJust,
+    try, tryJust,
+    evaluate,
+    mapException,
+    mask, mask_,
+    uninterruptibleMask, uninterruptibleMask_,
+    getMaskingState, allowInterrupt,
+
+    assert, bracket, bracket_, bracketOnError, finally, onException,
+    
+    Data (..),
+    Typeable (..),
+
+    exhaustively, exhaustivelyM, exhaustivelyBy, exhaustivelyByM,
+    uniqSort, aggregate, aggregateBy, aggregateAL, tr,
+    segment2, segment3, count2, count3, count4
+
+  ) where
+
+import Prelude hiding (
+    fst, snd, id, (.), catch,
+    map, foldl, foldl1, foldr, foldr1, and, or,
+    concat, minimum, maximum, all, any, sum, product,
+    concatMap, elem, notElem,
+    mapM_, sequence_
+ )
+import qualified Prelude
+
+import Control.Applicative
+import Control.Arrow
+import Control.Category
+import Control.Exception
+import Control.Monad hiding (mapM_, sequence_, forM_, forM, msum)
+
+import Data.Bool
+import Data.Char
+import Data.Complex
+import Data.Data
+import Data.Either
+import Data.Foldable
+import Data.Function (fix, on)
+import Data.Functor
+import Data.Int
+import Data.List hiding (
+    map, foldl, foldl1, foldr, foldr1, and, or,
+    concat, minimum, maximum, all, any, sum, product,
+    concatMap, elem, notElem, foldl', minimumBy, maximumBy,
+    find, mapAccumL, mapAccumR
+ )
+import Data.Maybe (
+    Maybe (..),
+    fromJust, isJust, isNothing, listToMaybe,
+    maybeToList, catMaybes, fromMaybe, mapMaybe
+ )
+import Data.Monoid (
+    Monoid (..), (<>),
+    Dual (..), Endo (..), All (..), Any (..),
+    Sum (..), Product (..), First (..), Last (..)
+ )
+import Data.Ratio (
+    Ratio, Rational
+ )
+import Data.String (
+    IsString (..),
+    lines, unlines, words, unwords
+ )
+import Data.Traversable hiding (mapM, sequence)
+import Data.Tuple
+import Data.Typeable
+import Data.Word
+
+import System.Environment
+import System.Exit
+import System.IO
+
+import Haskell.X
+import Haskell.X.Ops
+
+map :: Functor f => (a -> b) -> f a -> f b
+map = fmap
+
+class AtLeastPair a where
+    type Fst a
+    type Snd a
+
+    fst :: a -> Fst a
+    snd :: a -> Snd a
+
+instance AtLeastPair (a, b) where
+    type Fst (a, b) = a
+    type Snd (a, b) = b
+
+    fst (a, _) = a
+    snd (_, b) = b
+
+instance AtLeastPair (a, b, c) where
+    type Fst (a, b, c) = a
+    type Snd (a, b, c) = b
+    
+    fst (a, _, _) = a
+    snd (_, b, _) = b
+
+instance AtLeastPair (a, b, c, d) where
+    type Fst (a, b, c, d) = a
+    type Snd (a, b, c, d) = b
+    
+    fst (a, _, _, _) = a
+    snd (_, b, _, _) = b
+
+instance AtLeastPair (a, b, c, d, e) where
+    type Fst (a, b, c, d, e) = a
+    type Snd (a, b, c, d, e) = b
+    
+    fst (a, _, _, _, _) = a
+    snd (_, b, _, _, _) = b
+
+
+
+
