diff --git a/AUTHORS b/AUTHORS
new file mode 100644
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,1 @@
+Corentin Dupont <corentin.dupont@gmail.com>
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2016, Corentin Dupont. All rights reserved.
+
+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 its 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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,11 @@
+
+Shortcut
+========
+
+Class of parallel computations that can be interrupted.
+
+Contact
+=======
+
+Bug-reports, questions, suggestions and patches are all welcome.
+
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,6 @@
+#!/usr/bin/runhaskell 
+> module Main where
+> import Distribution.Simple
+> main :: IO ()
+> main = defaultMain
+
diff --git a/shortcut.cabal b/shortcut.cabal
new file mode 100644
--- /dev/null
+++ b/shortcut.cabal
@@ -0,0 +1,28 @@
+name: shortcut
+version: 0.1
+cabal-version: >=1.8
+build-type: Simple
+license: BSD3
+license-file: LICENSE
+copyright: 2016 Corentin Dupont
+maintainer: Corentin Dupont
+stability: Experimental
+description: A class for interruptible computations
+category: Language
+Homepage: http://www.nomyx.net
+author: Corentin Dupont
+data-files:
+data-dir: ""
+extra-source-files: AUTHORS README.md
+
+library
+    build-depends: base               >= 4.6 && < 5
+    exposed-modules: Control.Shortcut
+    exposed: True
+    buildable: True
+    hs-source-dirs: src
+    ghc-options: -W
+
+source-repository head
+  type:              git
+  location:          https://github.com/cdupont/shortcut.git
diff --git a/src/Control/Shortcut.hs b/src/Control/Shortcut.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Shortcut.hs
@@ -0,0 +1,40 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Control.Shortcut where
+
+import Data.Maybe
+
+-- | class of things that can be run in parallel and can be shortcuted.
+-- The funtion in parameter is called everytime an intermediate result is known, as soon as it
+-- returns True the intermediate results are returned (discarding those not yet available).
+-- the order of the lists must be preserved
+class Shortcutable s where
+   shortcut :: [s a] -> ([Maybe a] -> Bool) -> s [Maybe a]
+
+-- | version without the maybes
+shortcut_ :: (Functor s, Shortcutable s) => [s a] -> ([a] -> Bool) -> s [a]
+shortcut_ as f = catMaybes <$> shortcut as (f . catMaybes)
+
+-- |  version with two different types of result
+shortcut2 :: (Functor s, Monad s, Shortcutable s) => [s a] -> [s b] -> ([Maybe a] -> [Maybe b] -> Bool) -> s ([Maybe a], [Maybe b])
+shortcut2 as bs f = do
+  let stripEitherFst aes = map (fromLeft <$>) $ take (length as) aes
+  let stripEitherLst bes = map (fromRight <$>) $ drop (length as) bes
+  let f' abs = f (stripEitherFst abs) (stripEitherLst abs)
+  mabs <- shortcut ((map (Left <$>) as) ++ (map (Right <$>) bs)) f'
+  return (stripEitherFst mabs, stripEitherLst mabs)
+
+-- |  version with a supplementary event which result is discarded
+shortcut2b :: (Functor s, Monad s, Shortcutable s) => [s a] -> s b -> ([Maybe a] -> Bool -> Bool) -> s ([Maybe a], Bool)
+shortcut2b as b f = do
+   let f' as bs = f as (isJust $ head bs)
+   (as, bs) <- shortcut2 as [b] f'
+   return (as, isJust $ head bs)
+
+fromLeft           :: Either a b -> a
+fromLeft (Right _) = error "Argument takes form 'Right _'"
+fromLeft (Left x)  = x
+
+fromRight           :: Either a b -> b
+fromRight (Left _)  = error "Argument takes form 'Left _'"
+fromRight (Right x) = x
