step-function-0.2: Staircase functions or piecewise constant functions

Safe HaskellSafe
LanguageHaskell2010

Data.Function.Step.Discrete.Open

Contents

Synopsis

Step Function

Examples

>>> let heaviside = step 0 (-1) 1 :: SF Int Int
>>> putSF heaviside
\x -> if
    | x < 0     -> -1
    | otherwise -> 1
>>> map (heaviside !) [-3, 0, 4]
[-1,1,1]

data SF k v Source #

Step function. Piecewise constant function, having finitely many pieces. See https://en.wikipedia.org/wiki/Step_function.

Note: this variant has discrete domain. It's enough to have only <$, without , as there is a next element without any others in between.

SF (fromList [(k1, v1), (k2, v2)]) v3 :: SF k v describes a piecewise constant function \(f : k \to v\):

\[ f\,x = \begin{cases} v_1, \quad x < k_1 \newline v_2, \quad k_1 \le x < k_2 \newline v_3, \quad k_2 \le x \end{cases} \]

or as you would write in Haskell

f x | x < k1    = v1
    | x < k2    = v2
    | otherwise = v3

Constructor is exposed as you cannot construct non-valid SF.

Constructors

SF !(Map k v) !v 

Instances

Show2 SF Source # 

Methods

liftShowsPrec2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> Int -> SF a b -> ShowS #

liftShowList2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> [SF a b] -> ShowS #

Ord k => Monad (SF k) Source # 

Methods

(>>=) :: SF k a -> (a -> SF k b) -> SF k b #

(>>) :: SF k a -> SF k b -> SF k b #

return :: a -> SF k a #

fail :: String -> SF k a #

Functor (SF k) Source # 

Methods

fmap :: (a -> b) -> SF k a -> SF k b #

(<$) :: a -> SF k b -> SF k a #

Ord k => Applicative (SF k) Source #

pure is a constant function.

Methods

pure :: a -> SF k a #

(<*>) :: SF k (a -> b) -> SF k a -> SF k b #

liftA2 :: (a -> b -> c) -> SF k a -> SF k b -> SF k c #

(*>) :: SF k a -> SF k b -> SF k b #

(<*) :: SF k a -> SF k b -> SF k a #

Foldable (SF k) Source # 

Methods

fold :: Monoid m => SF k m -> m #

foldMap :: Monoid m => (a -> m) -> SF k a -> m #

foldr :: (a -> b -> b) -> b -> SF k a -> b #

foldr' :: (a -> b -> b) -> b -> SF k a -> b #

foldl :: (b -> a -> b) -> b -> SF k a -> b #

foldl' :: (b -> a -> b) -> b -> SF k a -> b #

foldr1 :: (a -> a -> a) -> SF k a -> a #

foldl1 :: (a -> a -> a) -> SF k a -> a #

toList :: SF k a -> [a] #

null :: SF k a -> Bool #

length :: SF k a -> Int #

elem :: Eq a => a -> SF k a -> Bool #

maximum :: Ord a => SF k a -> a #

minimum :: Ord a => SF k a -> a #

sum :: Num a => SF k a -> a #

product :: Num a => SF k a -> a #

Traversable (SF k) Source # 

Methods

traverse :: Applicative f => (a -> f b) -> SF k a -> f (SF k b) #

sequenceA :: Applicative f => SF k (f a) -> f (SF k a) #

mapM :: Monad m => (a -> m b) -> SF k a -> m (SF k b) #

sequence :: Monad m => SF k (m a) -> m (SF k a) #

Show k => Show1 (SF k) Source # 

Methods

liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> SF k a -> ShowS #

liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [SF k a] -> ShowS #

(Eq v, Eq k) => Eq (SF k v) Source # 

Methods

(==) :: SF k v -> SF k v -> Bool #

(/=) :: SF k v -> SF k v -> Bool #

(Ord v, Ord k) => Ord (SF k v) Source # 

Methods

compare :: SF k v -> SF k v -> Ordering #

(<) :: SF k v -> SF k v -> Bool #

(<=) :: SF k v -> SF k v -> Bool #

(>) :: SF k v -> SF k v -> Bool #

(>=) :: SF k v -> SF k v -> Bool #

max :: SF k v -> SF k v -> SF k v #

min :: SF k v -> SF k v -> SF k v #

(Show k, Show v) => Show (SF k v) Source # 

Methods

showsPrec :: Int -> SF k v -> ShowS #

show :: SF k v -> String #

showList :: [SF k v] -> ShowS #

(Ord k, Semigroup v) => Semigroup (SF k v) Source #

Piecewise <>.

>>> putSF $ step 0 "a" "b" <> step 1 "c" "d"
\x -> if
    | x < 0     -> "ac"
    | x < 1     -> "bc"
    | otherwise -> "bd"

Methods

(<>) :: SF k v -> SF k v -> SF k v #

sconcat :: NonEmpty (SF k v) -> SF k v #

stimes :: Integral b => b -> SF k v -> SF k v #

(Ord k, Monoid v) => Monoid (SF k v) Source # 

Methods

mempty :: SF k v #

mappend :: SF k v -> SF k v -> SF k v #

mconcat :: [SF k v] -> SF k v #

(Ord k, Arbitrary k, Arbitrary v) => Arbitrary (SF k v) Source # 

Methods

arbitrary :: Gen (SF k v) #

shrink :: SF k v -> [SF k v] #

(NFData k, NFData v) => NFData (SF k v) Source # 

Methods

rnf :: SF k v -> () #

Construction

constant :: a -> SF k a Source #

Constant function

>>> putSF $ constant 1
\_ -> 1

step :: k -> v -> v -> SF k v Source #

Step function.

step k v1 v2 = \ x -> if x < k then v1 else v2.

>>> putSF $ step 1 2 3
\x -> if
    | x < 1     -> 2
    | otherwise -> 3

fromList :: Ord k => [(k, v)] -> v -> SF k v Source #

Create function from list of cases and default value.

>>> putSF $ fromList [(1,2),(3,4)] 5
\x -> if
    | x < 1     -> 2
    | x < 3     -> 4
    | otherwise -> 5
>>> map (fromList [(1,2),(3,4)] 5 !) [0..10]
[2,4,4,5,5,5,5,5,5,5,5]

Normalisation

normalise :: Eq v => SF k v -> SF k v Source #

Merge adjustent pieces with same values.

Note: SF isn't normalised on construction. Values don't necessarily are Eq.

>>> putSF $ normalise heaviside
\x -> if
    | x < 0     -> -1
    | otherwise -> 1
>>> putSF $ normalise $ step 0 1 1
\_ -> 1
normalise (liftA2 (+) p (fmap negate p)) == (pure 0 :: SF Int Int)

Operators

(!) :: Ord k => SF k v -> k -> v infixl 9 Source #

Apply SF.

>>> heaviside ! 2
1

values :: SF k v -> [v] Source #

Possible values of SF

>>> values heaviside
[-1,1]

Conversions

toDense :: SF a b -> SF a b Source #

Convert from discrete variant to more "dense"

>>> SF.putSF $ toDense $ fromList [(1,2),(3,4)] 5
\x -> if
    | x < 1     -> 2
    | x < 3     -> 4
    | otherwise -> 5

fromDense Source #

Arguments

:: Ord a 
=> (a -> Maybe a)

next key, if exists

-> SF a b 
-> SF a b 

Convert from "dense" variant. <= k pieces will be converted to < succ k. There might be less pieces in the ressult SF, than in the original.

>>> let f = SF.fromList [(SF.Open 1,2),(SF.Closed 3,4),(SF.Open 4,5)] 6
>>> SF.putSF f
\x -> if
    | x <  1    -> 2
    | x <= 3    -> 4
    | x <  4    -> 5
    | otherwise -> 6
>>> putSF $ fromDense (Just . succ) f
\x -> if
    | x < 1     -> 2
    | x < 4     -> 4
    | otherwise -> 6

Debug

showSF :: (Show a, Show b) => SF a b -> String Source #

Show SF as Haskell code

putSF :: (Show a, Show b) => SF a b -> IO () Source #