-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Staircase functions or piecewise constant functions
--   
--   Step functions, staircase functions or piecewise constant functions.
--   Implemented as a default value and a series of transitions. Supports
--   merging two step functions using a supplied merging function.
@package step-function
@version 0.2

module Data.Function.Step

-- | Step function. Piecewise constant function, having finitely many
--   pieces. See <a>https://en.wikipedia.org/wiki/Step_function</a>.
--   
--   <tt><a>SF</a> (fromList [(<a>Open</a> k1, v1), (<a>Closed</a> k2,
--   v2)]) v3 :: <a>SF</a> k v</tt> describes a piecewise constant function
--   &lt;math&gt;:
--   
--   &lt;math&gt;
--   
--   or as you would write in Haskell
--   
--   <pre>
--   f x | x &lt;  k1   = v1
--       | x &lt;= k2   = v2
--       | otherwise = v3
--   </pre>
--   
--   <i>Note:</i> <a>total-map</a> package, which provides <i>function with
--   finite support</i>.
--   
--   Constructor is exposed as you cannot construct non-valid <a>SF</a>.
--   
--   <h3>Merging</h3>
--   
--   You can use <a>Applicative</a> instance to <i>merge</i> <a>SF</a>.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ liftA2 (+) (step 0 0 1) (step 1 0 1)
--   \x -&gt; if
--       | x &lt; 0     -&gt; 0
--       | x &lt; 1     -&gt; 1
--       | otherwise -&gt; 2
--   </pre>
--   
--   Following property holds, i.e. <a>SF</a> and ordinary function
--   <a>Applicative</a> instances are compatible (and <a>!</a> is a
--   homomorphism).
--   
--   <pre>
--   liftA2 f g h ! x == liftA2 f (g !) (h !) x
--   </pre>
--   
--   Recall that for ordinary functions <tt><a>liftA2</a> f g h x = f (g x)
--   (h x)</tt>.
--   
--   <h3>Dense?</h3>
--   
--   This dense variant is useful with <a>dense ordered</a> domains, e.g.
--   <a>Rational</a>. <a>Integer</a> is not dense, so you could use
--   <a>Data.Function.Step.Discrete</a> variant instead.
--   
--   <pre>
--   &gt;&gt;&gt; let s = fromList [(Open 0, -1),(Closed 0, 0)] 1 :: SF Rational Int
--   
--   &gt;&gt;&gt; putSF s
--   \x -&gt; if
--       | x &lt;  0 % 1 -&gt; -1
--       | x &lt;= 0 % 1 -&gt; 0
--       | otherwise  -&gt; 1
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; import Data.Ratio ((%))
--   
--   &gt;&gt;&gt; map (s !) [-1, -0.5, 0, 0.5, 1]
--   [-1,-1,0,1,1]
--   </pre>
data SF k v
SF :: !(Map (Bound k) v) -> !v -> SF k v

-- | Bound operations
data Bound k

-- | less-than, <tt>&lt;</tt>
Open :: k -> Bound k

-- | less-than-or-equal, <tt>≤</tt>.
Closed :: k -> Bound k

-- | Constant function
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ constant 1
--   \_ -&gt; 1
--   </pre>
constant :: a -> SF k a

-- | Step function.
--   
--   <tt><a>step</a> k v1 v2 = \ x -&gt; if x &lt; k then v1 else v2</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ step 1 2 3
--   \x -&gt; if
--       | x &lt; 1     -&gt; 2
--       | otherwise -&gt; 3
--   </pre>
step :: k -> v -> v -> SF k v

-- | Create function from list of cases and default value.
--   
--   <pre>
--   &gt;&gt;&gt; let f = fromList [(Open 1,2),(Closed 3,4),(Open 4,5)] 6
--   
--   &gt;&gt;&gt; putSF f
--   \x -&gt; if
--       | x &lt;  1    -&gt; 2
--       | x &lt;= 3    -&gt; 4
--       | x &lt;  4    -&gt; 5
--       | otherwise -&gt; 6
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; map (f !) [0..10]
--   [2,4,4,4,6,6,6,6,6,6,6]
--   </pre>
fromList :: Ord k => [(Bound k, v)] -> v -> SF k v

-- | Merge adjustent pieces with same values.
--   
--   <i>Note:</i> <a>SF</a> isn't normalised on construction. Values don't
--   necessarily are <a>Eq</a>.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ normalise heaviside
--   \x -&gt; if
--       | x &lt; 0     -&gt; -1
--       | otherwise -&gt; 1
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ normalise $ step 0 1 1
--   \_ -&gt; 1
--   </pre>
--   
--   <pre>
--   normalise (liftA2 (+) p (fmap negate p)) == (pure 0 :: SF Int Int)
--   </pre>
normalise :: Eq v => SF k v -> SF k v

-- | Apply <a>SF</a>.
--   
--   <pre>
--   &gt;&gt;&gt; heaviside ! 2
--   1
--   </pre>
(!) :: Ord k => SF k v -> k -> v
infixl 9 !

-- | Possible values of <a>SF</a>
--   
--   <pre>
--   &gt;&gt;&gt; values heaviside
--   [-1,1]
--   </pre>
values :: SF k v -> [v]

-- | Show <a>SF</a> as Haskell code
showSF :: (Show a, Show b) => SF a b -> String

-- | <pre>
--   <a>putStrLn</a> . <a>showSF</a>
--   </pre>
putSF :: (Show a, Show b) => SF a b -> IO ()
instance Data.Traversable.Traversable (Data.Function.Step.SF k)
instance Data.Foldable.Foldable (Data.Function.Step.SF k)
instance GHC.Base.Functor (Data.Function.Step.SF k)
instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.Function.Step.SF k v)
instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Function.Step.SF k v)
instance Data.Traversable.Traversable Data.Function.Step.Bound
instance Data.Foldable.Foldable Data.Function.Step.Bound
instance GHC.Base.Functor Data.Function.Step.Bound
instance GHC.Show.Show k => GHC.Show.Show (Data.Function.Step.Bound k)
instance GHC.Classes.Eq k => GHC.Classes.Eq (Data.Function.Step.Bound k)
instance GHC.Classes.Ord k => GHC.Base.Applicative (Data.Function.Step.SF k)
instance GHC.Classes.Ord k => GHC.Base.Monad (Data.Function.Step.SF k)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Semigroup (Data.Function.Step.SF k v)
instance (GHC.Classes.Ord k, GHC.Base.Monoid v) => GHC.Base.Monoid (Data.Function.Step.SF k v)
instance (GHC.Classes.Ord k, Test.QuickCheck.Arbitrary.Arbitrary k, Test.QuickCheck.Arbitrary.Arbitrary v) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Function.Step.SF k v)
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData v) => Control.DeepSeq.NFData (Data.Function.Step.SF k v)
instance Data.Functor.Classes.Show2 Data.Function.Step.SF
instance GHC.Show.Show k => Data.Functor.Classes.Show1 (Data.Function.Step.SF k)
instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Data.Function.Step.SF k v)
instance GHC.Classes.Ord k => GHC.Classes.Ord (Data.Function.Step.Bound k)
instance Test.QuickCheck.Arbitrary.Arbitrary k => Test.QuickCheck.Arbitrary.Arbitrary (Data.Function.Step.Bound k)
instance Control.DeepSeq.NFData k => Control.DeepSeq.NFData (Data.Function.Step.Bound k)
instance Data.Functor.Classes.Show1 Data.Function.Step.Bound

module Data.Function.Step.Discrete.Closed

-- | Step function. Piecewise constant function, having finitely many
--   pieces. See <a>https://en.wikipedia.org/wiki/Step_function</a>.
--   
--   <i>Note:</i> this variant has discrete domain. It's enough to have
--   only <tt>&lt;</tt>$, without <tt>≤</tt>, as there is a <i>next</i>
--   element without any others in between.
--   
--   <tt><a>SF</a> (fromList [(k1, v1), (k2, v2)]) v3 :: <a>SF</a> k v</tt>
--   describes a piecewise constant function &lt;math&gt;:
--   
--   &lt;math&gt;
--   
--   or as you would write in Haskell
--   
--   <pre>
--   f x | x &lt;= k1    = v1
--       | x &lt;= k2    = v2
--       | otherwise = v3
--   </pre>
--   
--   Constructor is exposed as you cannot construct non-valid <a>SF</a>.
data SF k v
SF :: !(Map k v) -> !v -> SF k v

-- | Constant function
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ constant 1
--   \_ -&gt; 1
--   </pre>
constant :: a -> SF k a

-- | Step function.
--   
--   <tt><a>step</a> k v1 v2 = \ x -&gt; if x &lt; k then v1 else v2</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ step 1 2 3
--   \x -&gt; if
--       | x &lt;= 1    -&gt; 2
--       | otherwise -&gt; 3
--   </pre>
step :: k -> v -> v -> SF k v

-- | Create function from list of cases and default value.
--   
--   <pre>
--   &gt;&gt;&gt; let f = fromList [(1,2),(3,4)] 5
--   
--   &gt;&gt;&gt; putSF f
--   \x -&gt; if
--       | x &lt;= 1    -&gt; 2
--       | x &lt;= 3    -&gt; 4
--       | otherwise -&gt; 5
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; map (f !) [0..10]
--   [2,2,4,4,5,5,5,5,5,5,5]
--   </pre>
fromList :: Ord k => [(k, v)] -> v -> SF k v

-- | Merge adjustent pieces with same values.
--   
--   <i>Note:</i> <a>SF</a> isn't normalised on construction. Values don't
--   necessarily are <a>Eq</a>.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ normalise heaviside
--   \x -&gt; if
--       | x &lt;= 0    -&gt; -1
--       | otherwise -&gt; 1
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ normalise $ step 0 1 1
--   \_ -&gt; 1
--   </pre>
--   
--   <pre>
--   normalise (liftA2 (+) p (fmap negate p)) == (pure 0 :: SF Int Int)
--   </pre>
normalise :: Eq v => SF k v -> SF k v

-- | Apply <a>SF</a>.
--   
--   <pre>
--   &gt;&gt;&gt; heaviside ! 2
--   1
--   </pre>
(!) :: Ord k => SF k v -> k -> v
infixl 9 !

-- | Possible values of <a>SF</a>
--   
--   <pre>
--   &gt;&gt;&gt; values heaviside
--   [-1,1]
--   </pre>
values :: SF k v -> [v]

-- | Convert from discrete variant to more "dense"
--   
--   <pre>
--   &gt;&gt;&gt; SF.putSF $ toDense $ fromList [(1,2),(3,4)] 5
--   \x -&gt; if
--       | x &lt;= 1    -&gt; 2
--       | x &lt;= 3    -&gt; 4
--       | otherwise -&gt; 5
--   </pre>
toDense :: SF a b -> SF a b

-- | Convert from "dense" variant. <tt>&lt;= k</tt> pieces will be
--   converted to <tt>&lt; <a>succ</a> k</tt>. There might be less pieces
--   in the ressult <a>SF</a>, than in the original.
--   
--   <pre>
--   &gt;&gt;&gt; let f = SF.fromList [(SF.Open 1,2),(SF.Closed 3,4),(SF.Open 4,5)] 6
--   
--   &gt;&gt;&gt; SF.putSF f
--   \x -&gt; if
--       | x &lt;  1    -&gt; 2
--       | x &lt;= 3    -&gt; 4
--       | x &lt;  4    -&gt; 5
--       | otherwise -&gt; 6
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ fromDense (Just . pred) f
--   \x -&gt; if
--       | x &lt;= 0    -&gt; 2
--       | x &lt;= 3    -&gt; 4
--       | otherwise -&gt; 6
--   </pre>
fromDense :: Ord a => (a -> Maybe a) -> SF a b -> SF a b

-- | Show <a>SF</a> as Haskell code
showSF :: (Show a, Show b) => SF a b -> String

-- | <pre>
--   <a>putStrLn</a> . <a>showSF</a>
--   </pre>
putSF :: (Show a, Show b) => SF a b -> IO ()
instance Data.Traversable.Traversable (Data.Function.Step.Discrete.Closed.SF k)
instance Data.Foldable.Foldable (Data.Function.Step.Discrete.Closed.SF k)
instance GHC.Base.Functor (Data.Function.Step.Discrete.Closed.SF k)
instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.Function.Step.Discrete.Closed.SF k v)
instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Function.Step.Discrete.Closed.SF k v)
instance GHC.Classes.Ord k => GHC.Base.Applicative (Data.Function.Step.Discrete.Closed.SF k)
instance GHC.Classes.Ord k => GHC.Base.Monad (Data.Function.Step.Discrete.Closed.SF k)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Semigroup (Data.Function.Step.Discrete.Closed.SF k v)
instance (GHC.Classes.Ord k, GHC.Base.Monoid v) => GHC.Base.Monoid (Data.Function.Step.Discrete.Closed.SF k v)
instance (GHC.Classes.Ord k, Test.QuickCheck.Arbitrary.Arbitrary k, Test.QuickCheck.Arbitrary.Arbitrary v) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Function.Step.Discrete.Closed.SF k v)
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData v) => Control.DeepSeq.NFData (Data.Function.Step.Discrete.Closed.SF k v)
instance Data.Functor.Classes.Show2 Data.Function.Step.Discrete.Closed.SF
instance GHC.Show.Show k => Data.Functor.Classes.Show1 (Data.Function.Step.Discrete.Closed.SF k)
instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Data.Function.Step.Discrete.Closed.SF k v)

module Data.Function.Step.Discrete.Open

-- | Step function. Piecewise constant function, having finitely many
--   pieces. See <a>https://en.wikipedia.org/wiki/Step_function</a>.
--   
--   <i>Note:</i> this variant has discrete domain. It's enough to have
--   only <tt>&lt;</tt>$, without <tt>≤</tt>, as there is a <i>next</i>
--   element without any others in between.
--   
--   <tt><a>SF</a> (fromList [(k1, v1), (k2, v2)]) v3 :: <a>SF</a> k v</tt>
--   describes a piecewise constant function &lt;math&gt;:
--   
--   &lt;math&gt;
--   
--   or as you would write in Haskell
--   
--   <pre>
--   f x | x &lt; k1    = v1
--       | x &lt; k2    = v2
--       | otherwise = v3
--   </pre>
--   
--   Constructor is exposed as you cannot construct non-valid <a>SF</a>.
data SF k v
SF :: !(Map k v) -> !v -> SF k v

-- | Constant function
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ constant 1
--   \_ -&gt; 1
--   </pre>
constant :: a -> SF k a

-- | Step function.
--   
--   <tt><a>step</a> k v1 v2 = \ x -&gt; if x &lt; k then v1 else v2</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ step 1 2 3
--   \x -&gt; if
--       | x &lt; 1     -&gt; 2
--       | otherwise -&gt; 3
--   </pre>
step :: k -> v -> v -> SF k v

-- | Create function from list of cases and default value.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ fromList [(1,2),(3,4)] 5
--   \x -&gt; if
--       | x &lt; 1     -&gt; 2
--       | x &lt; 3     -&gt; 4
--       | otherwise -&gt; 5
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; map (fromList [(1,2),(3,4)] 5 !) [0..10]
--   [2,4,4,5,5,5,5,5,5,5,5]
--   </pre>
fromList :: Ord k => [(k, v)] -> v -> SF k v

-- | Merge adjustent pieces with same values.
--   
--   <i>Note:</i> <a>SF</a> isn't normalised on construction. Values don't
--   necessarily are <a>Eq</a>.
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ normalise heaviside
--   \x -&gt; if
--       | x &lt; 0     -&gt; -1
--       | otherwise -&gt; 1
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ normalise $ step 0 1 1
--   \_ -&gt; 1
--   </pre>
--   
--   <pre>
--   normalise (liftA2 (+) p (fmap negate p)) == (pure 0 :: SF Int Int)
--   </pre>
normalise :: Eq v => SF k v -> SF k v

-- | Apply <a>SF</a>.
--   
--   <pre>
--   &gt;&gt;&gt; heaviside ! 2
--   1
--   </pre>
(!) :: Ord k => SF k v -> k -> v
infixl 9 !

-- | Possible values of <a>SF</a>
--   
--   <pre>
--   &gt;&gt;&gt; values heaviside
--   [-1,1]
--   </pre>
values :: SF k v -> [v]

-- | Convert from discrete variant to more "dense"
--   
--   <pre>
--   &gt;&gt;&gt; SF.putSF $ toDense $ fromList [(1,2),(3,4)] 5
--   \x -&gt; if
--       | x &lt; 1     -&gt; 2
--       | x &lt; 3     -&gt; 4
--       | otherwise -&gt; 5
--   </pre>
toDense :: SF a b -> SF a b

-- | Convert from "dense" variant. <tt>&lt;= k</tt> pieces will be
--   converted to <tt>&lt; <a>succ</a> k</tt>. There might be less pieces
--   in the ressult <a>SF</a>, than in the original.
--   
--   <pre>
--   &gt;&gt;&gt; let f = SF.fromList [(SF.Open 1,2),(SF.Closed 3,4),(SF.Open 4,5)] 6
--   
--   &gt;&gt;&gt; SF.putSF f
--   \x -&gt; if
--       | x &lt;  1    -&gt; 2
--       | x &lt;= 3    -&gt; 4
--       | x &lt;  4    -&gt; 5
--       | otherwise -&gt; 6
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putSF $ fromDense (Just . succ) f
--   \x -&gt; if
--       | x &lt; 1     -&gt; 2
--       | x &lt; 4     -&gt; 4
--       | otherwise -&gt; 6
--   </pre>
fromDense :: Ord a => (a -> Maybe a) -> SF a b -> SF a b

-- | Show <a>SF</a> as Haskell code
showSF :: (Show a, Show b) => SF a b -> String

-- | <pre>
--   <a>putStrLn</a> . <a>showSF</a>
--   </pre>
putSF :: (Show a, Show b) => SF a b -> IO ()
instance Data.Traversable.Traversable (Data.Function.Step.Discrete.Open.SF k)
instance Data.Foldable.Foldable (Data.Function.Step.Discrete.Open.SF k)
instance GHC.Base.Functor (Data.Function.Step.Discrete.Open.SF k)
instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.Function.Step.Discrete.Open.SF k v)
instance (GHC.Classes.Eq k, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Function.Step.Discrete.Open.SF k v)
instance GHC.Classes.Ord k => GHC.Base.Applicative (Data.Function.Step.Discrete.Open.SF k)
instance GHC.Classes.Ord k => GHC.Base.Monad (Data.Function.Step.Discrete.Open.SF k)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Semigroup (Data.Function.Step.Discrete.Open.SF k v)
instance (GHC.Classes.Ord k, GHC.Base.Monoid v) => GHC.Base.Monoid (Data.Function.Step.Discrete.Open.SF k v)
instance (GHC.Classes.Ord k, Test.QuickCheck.Arbitrary.Arbitrary k, Test.QuickCheck.Arbitrary.Arbitrary v) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Function.Step.Discrete.Open.SF k v)
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData v) => Control.DeepSeq.NFData (Data.Function.Step.Discrete.Open.SF k v)
instance Data.Functor.Classes.Show2 Data.Function.Step.Discrete.Open.SF
instance GHC.Show.Show k => Data.Functor.Classes.Show1 (Data.Function.Step.Discrete.Open.SF k)
instance (GHC.Show.Show k, GHC.Show.Show v) => GHC.Show.Show (Data.Function.Step.Discrete.Open.SF k v)


-- | This module re-exports <a>Function.Step.Discrete.Open</a>
module Data.Function.Step.Discrete
