diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2024 Nikita Volkov
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/combinators.cabal b/combinators.cabal
new file mode 100644
--- /dev/null
+++ b/combinators.cabal
@@ -0,0 +1,39 @@
+cabal-version: 3.0
+name: combinators
+version: 0.1
+synopsis: Collection of combinators over standard typeclasses
+homepage: https://github.com/nikita-volkov/combinators
+bug-reports: https://github.com/nikita-volkov/combinators/issues
+author: Nikita Volkov <nikita.y.volkov@mail.ru>
+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>
+copyright: (c) 2024 Nikita Volkov
+license: MIT
+license-file: LICENSE
+
+source-repository head
+  type: git
+  location: git://github.com/nikita-volkov/combinators.git
+
+common base
+  default-language: Haskell2010
+  default-extensions:
+    BlockArguments
+    DefaultSignatures
+    FlexibleContexts
+    FlexibleInstances
+    MagicHash
+    MultiParamTypeClasses
+    NoImplicitPrelude
+    ScopedTypeVariables
+    TypeApplications
+    UndecidableSuperClasses
+
+library
+  import: base
+  hs-source-dirs: src/library
+  exposed-modules:
+    Combinators
+
+  build-depends:
+    base >=4.12 && <5,
+    mtl >=2.2.2 && <3,
diff --git a/src/library/Combinators.hs b/src/library/Combinators.hs
new file mode 100644
--- /dev/null
+++ b/src/library/Combinators.hs
@@ -0,0 +1,52 @@
+module Combinators where
+
+import Control.Applicative
+import Control.Monad
+import Control.Monad.State.Strict
+import Data.Foldable
+import Data.Function
+import Data.Int
+import Data.Traversable
+import GHC.Enum
+
+-- * Alternation
+
+-- |
+-- Generalization over many common natural transformations, including:
+--
+-- - 'listToMaybe'
+-- - 'maybeToList'
+-- - 'toList'
+-- - @'either' ('const' 'Nothing') 'Just'@
+{-# INLINE alternate #-}
+alternate :: (Foldable f, Alternative g) => f a -> g a
+alternate = alternateMapM pure
+
+-- |
+-- 'alternate' extended with ability to map the wrapped value.
+{-# INLINE alternateMap #-}
+alternateMap :: (Foldable f, Alternative g) => (a -> b) -> f a -> g b
+alternateMap mapper = alternateMapM (pure . mapper)
+
+-- |
+-- 'alternateMap' extended with ability to do the mapping in the 'Alternative' context.
+{-# INLINE alternateMapM #-}
+alternateMapM :: (Foldable f, Alternative g) => (a -> g b) -> f a -> g b
+alternateMapM mapper = foldr cons empty
+  where
+    cons a b = mapper a <|> b
+
+-- * Traversal
+
+-- |
+-- Indexed version of 'forM'.
+{-# INLINE iforM #-}
+iforM :: (Monad m, Traversable f) => f a -> (Int -> a -> m b) -> m (f b)
+iforM collection f =
+  collection
+    & traverse
+      ( \item -> do
+          i <- state (\i -> (i, succ i))
+          lift (f i item)
+      )
+    & flip evalStateT 0
