diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2015 Gabriel Gonzalez
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * 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.
+    * Neither the name of Gabriel Gonzalez nor the names of other contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT OWNER 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.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/optional-args.cabal b/optional-args.cabal
new file mode 100644
--- /dev/null
+++ b/optional-args.cabal
@@ -0,0 +1,26 @@
+Name: optional-args
+Version: 1.0.0
+Cabal-Version: >=1.10
+Build-Type: Simple
+License: BSD3
+License-File: LICENSE
+Copyright: 2015 Gabriel Gonzalez
+Author: Gabriel Gonzalez
+Maintainer: Gabriel439@gmail.com
+Bug-Reports: https://github.com/Gabriel439/Haskell-Optional-Args-Library/issues
+Synopsis: Optional function arguments
+Description: This library provides a type for specifying `Optional` function
+  arguments
+  .
+  Read the tutorial in "Data.Optional" to learn more
+Category: Data
+Source-Repository head
+    Type: git
+    Location: https://github.com/Gabriel439/Haskell-Optional-Args-Library
+
+Library
+    HS-Source-Dirs: src
+    Build-Depends: base >= 4.5 && < 5
+    Exposed-Modules: Data.Optional
+    GHC-Options: -O2 -Wall
+    Default-Language: Haskell2010
diff --git a/src/Data/Optional.hs b/src/Data/Optional.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Optional.hs
@@ -0,0 +1,149 @@
+{-# LANGUAGE DeriveFunctor     #-}
+{-# LANGUAGE DeriveFoldable    #-}
+{-# LANGUAGE DeriveTraversable #-}
+
+-- | Use the `Optional` type for optional function arguments.  For example:
+-- 
+-- > import Data.Optional
+-- >
+-- > greet :: Optional String -> String
+-- > greet (Specific name) = "Hello, " ++ name
+-- > greet  Default        = "Hello"
+-- 
+-- >>> greet (Specific "John")
+-- "Hello, John"
+-- >>> greet Default
+-- "Hello"
+-- 
+--     The `Optional` type overloads as many Haskell literals as possible so
+--     that you do not need to wrap values in `Specific`.  For example, if you
+--     enable the `OverloadedStrings` extension you can use a naked string
+--     literal instead:
+-- 
+-- >>> :set -XOverloadedStrings
+-- >>> greet "John"
+-- "Hello, John"
+-- 
+--     The `Optional` type also implements `Num` and `Fractional`, so you can
+--     use numeric literals in place of `Optional` values:
+-- 
+-- > birthday :: Optional Int -> String
+-- > birthday (Specific age) = "You are " ++ show age ++ " years old!"
+-- > birthday  Default       = "You are one year older!"
+-- 
+-- >>> birthday 20
+-- "You are 20 years old!"
+-- >>> birthday Default
+-- "You are one year older!"
+-- 
+--     The `IsString`, `Num`, and `Fractional` instances are recursive, so you
+--     can wrap your types in a more descriptive newtype and derive `IsString`,
+--     `Num` or `Fractional`:
+-- 
+-- > {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+-- > 
+-- > import Data.Optional
+-- > import Data.String (IsString)
+-- > 
+-- > newtype Name = Name { getName :: String } deriving (IsString)
+-- > 
+-- > greet :: Optional Name -> String
+-- > greet (Specific name) = "Hello, " ++ getName name
+-- > greet  Default        = "Hello"
+-- > 
+-- > newtype Age = Age { getAge :: Int } deriving (Num)
+-- > 
+-- > birthday :: Optional Age -> String
+-- > birthday (Specific age) = "You are " ++ show (getAge age) ++ " years old!"
+-- > birthday  Default       = "You are one year older!"
+-- 
+--     ... and you would still be able to provide naked numeric or string
+--     literals:
+-- 
+-- >>> :set -XOverloadedStrings
+-- >>> greet "John"
+-- "Hello, John"
+-- >>> birthday 20
+-- "You are 20 years old!"
+-- 
+--     You can use `empty` as a short-hand for a `Default` argument:
+-- 
+-- >>> greet empty
+-- "Hello"
+-- >>> birthday empty
+-- "You are one year older!"
+-- 
+--     You can also use `pure` as a short-hand for a `Specific` argument:
+-- 
+-- >>> greet (pure "John")
+-- "Hello, John"
+-- >>> birthday (pure 20)
+-- "You are 20 years old!"
+
+module Data.Optional (
+    -- * Optional
+      Optional(..)
+
+    -- * Re-exports
+    , empty
+    , pure
+    ) where
+
+import Control.Applicative (Applicative(..), Alternative(..), liftA2)
+import Control.Monad (MonadPlus(..))
+import Data.Foldable (Foldable)
+import Data.Traversable (Traversable)
+import Data.Monoid (Monoid(..))
+import Data.String (IsString(..))
+
+-- | A function argument that has a `Default` value
+data Optional a = Default | Specific a
+    deriving (Eq, Functor, Foldable, Traversable, Show)
+
+instance Applicative Optional where
+    pure = Specific
+
+    Specific f <*> Specific x = Specific (f x)
+    _          <*> _          = Default
+
+instance Monad Optional where
+    return = Specific
+
+    Default    >>= _ = Default
+    Specific x >>= f = f x
+
+instance Alternative Optional where
+    empty = Default
+
+    Default <|> x = x
+    x       <|> _ = x
+
+instance MonadPlus Optional where
+    mzero = empty
+    mplus = (<|>)
+
+instance Monoid a => Monoid (Optional a) where
+    mempty = pure mempty
+
+    mappend = liftA2 mappend
+
+instance IsString a => IsString (Optional a) where
+    fromString str = pure (fromString str)
+
+instance Num a => Num (Optional a) where
+    fromInteger n = pure (fromInteger n)
+
+    (+) = liftA2 (+)
+    (*) = liftA2 (*)
+    (-) = liftA2 (-)
+
+    negate = fmap negate
+    abs    = fmap abs
+    signum = fmap signum
+
+instance Fractional a => Fractional (Optional a) where
+    fromRational n = pure (fromRational n)
+
+    recip = fmap recip
+
+    (/) = liftA2 (/)
