    -- | Basic definitions for stencil handling.
    module Data.Array.Repa.Stencil.Base
    	( Boundary	(..)
    	, Stencil	(..)
    	, makeStencil, makeStencil2)
    where
    import Data.Array.Repa.Index

    -- | How to handle the case when the stencil lies partly outside the array.
    data Boundary a
            -- | Use a fixed value for border regions.
            = BoundFixed !a

    	-- | Treat points outside the array as having a constant value.
    	| BoundConst !a

    	-- | Clamp points outside to the same value as the edge pixel.
    	| BoundClamp
    	deriving (Show)

    -- | Represents a convolution stencil that we can apply to array.
    --   Only statically known stencils are supported right now.
    data Stencil sh a

    	-- | Static stencils are used when the coefficients are fixed,
    	--   and known at compile time.
    	= StencilStatic
    	{ stencilExtent	:: !sh
    	, stencilZero	:: !a
    	, stencilAcc	:: !(sh -> a -> a -> a) }

    -- | Make a stencil from a function yielding coefficients at each index.
    makeStencil
    	:: Num a
    	=> sh			-- ^ Extent of stencil.
    	-> (sh -> Maybe a) 	-- ^ Get the coefficient at this index.
    	-> Stencil sh a

    {-# INLINE makeStencil #-}
    makeStencil ex getCoeff
     = StencilStatic ex 0
     $ \ix val acc
    	-> case getCoeff ix of
    		Nothing		-> acc
    		Just coeff	-> acc + val * coeff

    -- | Wrapper for `makeStencil` that requires a DIM2 stencil.
    makeStencil2
    	:: Num a
    	=> Int -> Int		-- ^ extent of stencil
    	-> (DIM2 -> Maybe a)	-- ^ Get the coefficient at this index.
    	-> Stencil DIM2 a

    {-# INLINE makeStencil2 #-}
    makeStencil2 height width getCoeff
    	= makeStencil (Z :. height :. width) getCoeff