diff --git a/massiv.cabal b/massiv.cabal
--- a/massiv.cabal
+++ b/massiv.cabal
@@ -1,5 +1,5 @@
 name:                massiv
-version:             0.1.5.0
+version:             0.1.6.0
 synopsis:            Massiv (Массив) is an Array Library.
 description:         Multi-dimensional Arrays with fusion, stencils and parallel computation.
 homepage:            https://github.com/lehins/massiv
@@ -57,6 +57,10 @@
                      , ghc-prim
                      , primitive
                      , vector
+
+  if impl(ghc < 8.0)
+    build-depends: semigroups
+
   default-language:    Haskell2010
   ghc-options:         -Wall
 
diff --git a/src/Data/Massiv/Array/Ops/Fold.hs b/src/Data/Massiv/Array/Ops/Fold.hs
--- a/src/Data/Massiv/Array/Ops/Fold.hs
+++ b/src/Data/Massiv/Array/Ops/Fold.hs
@@ -18,6 +18,7 @@
 
     fold
   , foldMono
+  , foldSemi
   , minimum
   , maximum
   , sum
@@ -71,7 +72,7 @@
 import           Data.Massiv.Array.Ops.Map           (map)
 import           Data.Massiv.Core
 import           Data.Massiv.Core.Common
-import           Data.Monoid
+import           Data.Semigroup
 import           Prelude                             hiding (all, and, any,
                                                       foldl, foldr, map,
                                                       maximum, minimum, or,
@@ -85,10 +86,23 @@
   => (e -> m) -- ^ Convert each element of an array to an appropriate `Monoid`.
   -> Array r ix e -- ^ Source array
   -> m
-foldMono f = foldl (<>) mempty (<>) mempty . map f
+foldMono f = foldl mappend mempty mappend mempty . map f
 {-# INLINE foldMono #-}
 
 
+-- | /O(n)/ - Semigroup fold over an array.
+--
+-- @since 0.1.6
+foldSemi ::
+     (Source r ix e, Semigroup m)
+  => (e -> m) -- ^ Convert each element of an array to an appropriate `Semigroup`.
+  -> m -- ^ Initial element that must be neutral to the (`<>`) function.
+  -> Array r ix e -- ^ Source array
+  -> m
+foldSemi f m = foldl (<>) m (<>) m . map f
+{-# INLINE foldSemi #-}
+
+
 -- | /O(n)/ - Compute maximum of all elements.
 maximum :: (Source r ix e, Ord e) =>
            Array r ix e -> e
@@ -105,7 +119,7 @@
 minimum = \arr ->
   if isEmpty arr
     then error "Data.Massiv.Array.minimum - empty"
-    else fold max (evaluateAt arr zeroIndex) arr
+    else fold min (evaluateAt arr zeroIndex) arr
 {-# INLINE minimum #-}
 
 
diff --git a/src/Data/Massiv/Array/Stencil/Internal.hs b/src/Data/Massiv/Array/Stencil/Internal.hs
--- a/src/Data/Massiv/Array/Stencil/Internal.hs
+++ b/src/Data/Massiv/Array/Stencil/Internal.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE BangPatterns          #-}
+{-# LANGUAGE CPP                   #-}
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
@@ -16,9 +17,14 @@
 
 import           Control.Applicative
 import           Control.DeepSeq
-import           Data.Massiv.Core.Common
+import           Data.Default.Class                 (Default (def))
 import           Data.Massiv.Array.Delayed.Internal
-import           Data.Default.Class                (Default (def))
+import           Data.Massiv.Array.Delayed.Windowed
+import           Data.Massiv.Core.Common
+import           GHC.Exts                           (inline)
+#if !MIN_VERSION_base(4,11,0)
+import           Data.Semigroup
+#endif
 
 -- | Stencil is abstract description of how to handle elements in the neighborhood of every array
 -- cell in order to compute a value for the cells in the new array. Use `Data.Array.makeStencil` and
@@ -38,7 +44,6 @@
 -- it possible to manipulate the value, without having direct access to it.
 newtype Value e = Value { unValue :: e } deriving (Show, Eq, Ord, Bounded)
 
-
 instance Functor Value where
   fmap f (Value e) = Value (f e)
   {-# INLINE fmap #-}
@@ -49,6 +54,18 @@
   (<*>) (Value f) (Value e) = Value (f e)
   {-# INLINE (<*>) #-}
 
+-- | @since 0.1.5
+instance Semigroup a => Semigroup (Value a) where
+  Value a <> Value b = Value (a <> b)
+  {-# INLINE (<>) #-}
+
+-- | @since 0.1.5
+instance Monoid a => Monoid (Value a) where
+  mempty = Value mempty
+  {-# INLINE mempty #-}
+  Value a `mappend` Value b = Value (a `mappend` b)
+  {-# INLINE mappend #-}
+
 instance Num e => Num (Value e) where
   (+) = liftA2 (+)
   {-# INLINE (+) #-}
@@ -222,3 +239,32 @@
   in stencil (Value . safeStencilIndex valArr) sCenter `seq` s
 {-# INLINE validateStencil #-}
 
+
+-- | This is an unsafe version of the stencil computation. There are no bounds check further from
+-- the border, so if you make sure you don't go outside the size of the stencil, you will be safe,
+-- but this is not enforced.
+forStencilUnsafe ::
+     (Source r ix e, Manifest r ix e)
+  => Array r ix e
+  -> ix -- ^ Size of the stencil
+  -> ix -- ^ Center of the stencil
+  -> ((ix -> Maybe e) -> a)
+  -- ^ Stencil function that receives a "get" function as it's argument that can
+  -- retrieve values of cells in the source array with respect to the center of
+  -- the stencil. Stencil function must return a value that will be assigned to
+  -- the cell in the result array. Offset supplied to the "get" function
+  -- cannot go outside the boundaries of the stencil, otherwise an error will be
+  -- raised during stencil creation.
+  -> Array DW ix a
+forStencilUnsafe !arr !sSz !sCenter relStencil =
+  DWArray
+    (DArray (getComp arr) sz (stencil (index arr)))
+    (Just sSz)
+    sCenter
+    (liftIndex2 (-) sz (liftIndex2 (-) sSz (pureIndex 1)))
+    (stencil (Just . unsafeIndex arr))
+  where
+    stencil getVal !ix = (inline relStencil $ \ !ixD -> getVal (liftIndex2 (+) ix ixD))
+    {-# INLINE stencil #-}
+    !sz = size arr
+{-# INLINE forStencilUnsafe #-}
diff --git a/src/Data/Massiv/Array/Unsafe.hs b/src/Data/Massiv/Array/Unsafe.hs
--- a/src/Data/Massiv/Array/Unsafe.hs
+++ b/src/Data/Massiv/Array/Unsafe.hs
@@ -39,11 +39,14 @@
   , unsafeLinearRead
   , unsafeWrite
   , unsafeLinearWrite
+  -- * Stencil
+  , forStencilUnsafe
   ) where
 
 import           Control.Monad.Primitive            (PrimMonad (..))
 import           Control.Monad.ST                   (runST)
 import           Data.Massiv.Array.Delayed.Internal (D)
+import           Data.Massiv.Array.Stencil.Internal
 import           Data.Massiv.Core.Common
 import           Data.Massiv.Core.Scheduler
 import           System.IO.Unsafe                   (unsafePerformIO)
@@ -103,6 +106,8 @@
 
 
 -- | Create an array in parallel using mutable interface
+--
+-- @since 0.1.5
 unsafeGenerateArrayP :: Mutable r ix e => [Int] -> ix -> (ix -> e) -> Array r ix e
 unsafeGenerateArrayP wIds !sz f = unsafePerformIO $ do
   marr <- unsafeNew sz
diff --git a/src/Data/Massiv/Core/Computation.hs b/src/Data/Massiv/Core/Computation.hs
--- a/src/Data/Massiv/Core/Computation.hs
+++ b/src/Data/Massiv/Core/Computation.hs
@@ -15,16 +15,11 @@
   ) where
 
 import           Control.DeepSeq (NFData (..), deepseq)
-#if MIN_VERSION_base(4,9,0)
 #if !MIN_VERSION_base(4,11,0)
-import Data.Semigroup
-#endif
-instance Semigroup Comp where
-  (<>) = joinComp
+import           Data.Semigroup
 #endif
 
 
-
 -- | Computation type to use.
 data Comp
   = Seq -- ^ Sequential computation
@@ -58,6 +53,10 @@
   {-# INLINE mempty #-}
   mappend = joinComp
   {-# INLINE mappend #-}
+
+instance Semigroup Comp where
+  (<>) = joinComp
+  {-# INLINE (<>) #-}
 
 
 joinComp :: Comp -> Comp -> Comp
diff --git a/tests/Data/Massiv/Array/Ops/FoldSpec.hs b/tests/Data/Massiv/Array/Ops/FoldSpec.hs
--- a/tests/Data/Massiv/Array/Ops/FoldSpec.hs
+++ b/tests/Data/Massiv/Array/Ops/FoldSpec.hs
@@ -4,11 +4,14 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 module Data.Massiv.Array.Ops.FoldSpec (spec) where
 
-import           Data.Massiv.CoreArbitrary
+import qualified Data.Foldable             as F
+import           Data.Massiv.CoreArbitrary as A
+import           Data.Semigroup
 import           Prelude                   hiding (map, product, sum)
 import qualified Prelude                   as P (length, sum)
 import           Test.Hspec
 import           Test.QuickCheck
+import           Test.QuickCheck.Function
 import           Test.QuickCheck.Monadic
 
 
@@ -55,6 +58,20 @@
     it "sumS Eq sumP" $ property $ prop_SumSEqSumP proxy
     it "prodS Eq prodP" $ property $ prop_ProdSEqProdP proxy
 
+foldOpsProp :: (Source P ix Int) => proxy ix -> Fun Int Bool -> ArrTiny1 P ix Int -> Property
+foldOpsProp _ f (ArrTiny1 arr) =
+  (A.maximum arr === getMax (foldMono Max arr)) .&&.
+  (A.minimum arr === getMin (foldSemi Min maxBound arr)) .&&.
+  (A.sum arr === F.sum ls) .&&.
+  (A.product (A.map ((+ 0.1) . (fromIntegral :: Int -> Double)) arr) ===
+   getProduct (foldMono (Product . (+ 0.1) . fromIntegral) arr)) .&&.
+  (A.all (apply f) arr === F.all (apply f) ls) .&&.
+  (A.any (apply f) arr === F.any (apply f) ls) .&&.
+  (A.or (A.map (apply f) arr) === F.or (fmap (apply f) ls)) .&&.
+  (A.and (A.map (apply f) arr) === F.and (fmap (apply f) ls))
+  where
+    ls = toList arr
+
 spec :: Spec
 spec = do
   specFold (Nothing :: Maybe Ix1) "Ix1"
@@ -62,3 +79,7 @@
   it "Nested Parallel Fold" $ property prop_NestedFoldP
   it "FoldrOnP" $ property $ prop_FoldrOnP
   it "FoldlOnP" $ property $ prop_FoldlOnP
+  describe "Foldable Props" do
+    it "Ix1" $ property $ foldOpsProp (Nothing :: Maybe Ix1)
+    it "Ix2" $ property $ foldOpsProp (Nothing :: Maybe Ix2)
+    it "Ix3" $ property $ foldOpsProp (Nothing :: Maybe Ix3)
diff --git a/tests/Data/Massiv/CoreArbitrary.hs b/tests/Data/Massiv/CoreArbitrary.hs
--- a/tests/Data/Massiv/CoreArbitrary.hs
+++ b/tests/Data/Massiv/CoreArbitrary.hs
@@ -7,8 +7,10 @@
 module Data.Massiv.CoreArbitrary
   ( Arr(..)
   , ArrTiny(..)
+  , ArrTiny1(..)
   , ArrIx(..)
   , ArrP(..)
+  , ArrS(..)
   , ArrIxP(..)
   , Sz(..)
   , SzIx(..)
@@ -23,21 +25,23 @@
 
 import           Control.DeepSeq            (NFData, deepseq)
 import           Control.Exception          (Exception, SomeException, catch)
---import           Data.Massiv.Array.Ops.Construct
 import           Data.Massiv.Array
 import           Data.Massiv.Core.IndexSpec hiding (spec)
 import           Data.Typeable
 import           Test.QuickCheck
 import           Test.QuickCheck.Monadic
 
-data Arr r ix e = Arr (Array r ix e)
+newtype Arr r ix e = Arr {unArr :: Array r ix e}
 
-data ArrTiny r ix e = ArrTiny (Array r ix e)
+newtype ArrTiny r ix e = ArrTiny {unArrTiny :: Array r ix e}
 
-data ArrS r ix e = ArrS (Array r ix e)
+-- | Tiny but non-empty
+newtype ArrTiny1 r ix e = ArrTiny1 {unArrTiny1 :: Array r ix e}
 
-data ArrP r ix e = ArrP (Array r ix e)
+newtype ArrS r ix e = ArrS {unArrS :: Array r ix e}
 
+newtype ArrP r ix e = ArrP {unArrP :: Array r ix e}
+
 data ArrIx r ix e = ArrIx (Array r ix e) ix
 
 data ArrIxS r ix e = ArrIxS (Array r ix e) ix
@@ -46,6 +50,7 @@
 
 deriving instance (Show (Array r ix e)) => Show (Arr r ix e)
 deriving instance (Show (Array r ix e)) => Show (ArrTiny r ix e)
+deriving instance (Show (Array r ix e)) => Show (ArrTiny1 r ix e)
 deriving instance (Show (Array r ix e)) => Show (ArrS r ix e)
 deriving instance (Show (Array r ix e)) => Show (ArrP r ix e)
 deriving instance (Show (Array r ix e), Show ix) => Show (ArrIx r ix e)
@@ -74,6 +79,15 @@
     func <- arbitrary
     comp <- oneof [pure Seq, pure Par]
     return $ ArrTiny $ makeArray comp (liftIndex (`mod` 10) sz) func
+
+-- | Arbitrary small and possibly empty array. Computation strategy can be either `Seq` or `Par`.
+instance (CoArbitrary ix, Arbitrary ix, Typeable e, Construct r ix e, Arbitrary e) =>
+         Arbitrary (ArrTiny1 r ix e) where
+  arbitrary = do
+    SzZ sz <- arbitrary
+    func <- arbitrary
+    comp <- oneof [pure Seq, pure Par]
+    return $ ArrTiny1 $ makeArray comp (liftIndex (succ . (`mod` 10)) sz) func
 
 -- | Arbitrary non-empty array. Computation strategy can be either `Seq` or `Par`.
 instance (CoArbitrary ix, Arbitrary ix, Typeable e, Construct r ix e, Arbitrary e) =>
