packages feed

break (empty) → 1.0.0

raw patch · 4 files changed

+164/−0 lines, 4 filesdep +basedep +mtldep +transformerssetup-changed

Dependencies added: base, mtl, transformers

Files

+ LICENSE view
@@ -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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ break.cabal view
@@ -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
+ src/Control/Break.hs view
@@ -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