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/break.cabal b/break.cabal
new file mode 100644
--- /dev/null
+++ b/break.cabal
@@ -0,0 +1,29 @@
+Name: break
+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-Break-Library/issues
+Synopsis: Break from a loop
+Description: This library provides a simple and general API for exiting from
+    loops
+    .
+    Read the tutorial in "Control.Break" to learn more
+Category: Control
+Source-Repository head
+    Type: git
+    Location: https://github.com/Gabriel439/Haskell-Optional-Library
+
+Library
+    HS-Source-Dirs: src
+    Build-Depends:
+        base         >= 4.5     && < 5  ,
+        mtl          >= 2.1     && < 2.3,
+        transformers >= 0.4.0.0 && < 0.5
+    Exposed-Modules: Control.Break
+    GHC-Options: -O2 -Wall
+    Default-Language: Haskell2010
diff --git a/src/Control/Break.hs b/src/Control/Break.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Break.hs
@@ -0,0 +1,109 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+{-| Example usage:
+
+> import Control.Break
+> import Control.Monad.State
+> import Prelude hiding (break)
+>
+> example :: State Int ()
+> example = loop (do
+>     n <- lift get                -- Inside a `loop`, wrap commands in `lift`
+>     if n < 10
+>         then lift (put (n + 1))  -- You keep looping by default
+>         else break () )          -- Use `break` to exit from the `loop`
+
+The `loop` command runs the given command repeatedly until the command breaks
+from the `loop` using `break`:
+
+>>> execState example 0
+10
+
+For some effects (like `Control.Monad.Trans.State`), you can omit `lift`:
+
+> example :: State Int ()
+> example = loop (do
+>     n <- get
+>     if n < 10
+>         then put (n + 1)
+>         else break () )
+
+    The `loop` will return whatever value you supply to `break`:
+
+> example :: State Int Bool
+> example = loop (do
+>     n <- get
+>     if n < 10
+>         then put (n + 1)
+>         else break True )
+
+>>> runState example 0
+(True,10)
+
+-}
+
+module Control.Break (
+    -- * Break
+      Break
+    , loop
+    , break
+
+    -- * Re-exports
+    , lift
+    ) where
+
+import Control.Applicative (Applicative)
+import Control.Monad (forever)
+import Control.Monad.IO.Class (MonadIO)
+import Control.Monad.Trans.Class (MonadTrans(..))
+import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE)
+import Control.Monad.Cont   (MonadCont  )
+import Control.Monad.State  (MonadState )
+import Control.Monad.Writer (MonadWriter)
+import Prelude hiding (break)
+
+{-| For the most common use cases you will:
+
+    * build `Break` commands using `lift` or `break`
+
+    * combine `Break` commands using @do@ notation
+
+    * consume `Break` commands using `loop`
+
+    The meaning of the type parameters:
+
+    * @r@: the argument type of `break` and the return type of the `loop`
+
+    * @m@: the base `Monad` that you are running in a `loop`
+
+    * @a@: the return type of a `Break` command (not the same as the return
+      value of the `loop`)
+-}
+newtype Break r m a = Break { unBreak :: ExceptT r m a }
+    deriving
+    ( Functor
+    , Applicative
+    , Monad
+    , MonadTrans
+    , MonadIO
+    , MonadCont
+    , MonadState  s
+    , MonadWriter w
+    )
+
+{-| `break` from a `loop`
+
+    The argument you supply to `break` is the return value of the `loop`
+-}
+break :: Monad m => r -> Break r m a
+break r = Break (throwE r)
+
+{-| @(loop m)@ runs the action @\'m\'@ repeatedly until you `break` from the
+   `loop`
+-}
+loop :: Monad m => Break r m () -> m r
+loop m = do
+    x <- runExceptT (unBreak (forever m))
+    case x of
+        Left  r -> return r
+        Right r -> return r
