Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
- data SF k v = SF !(Map (Bound k) v) !v
- data Bound k
- constant :: a -> SF k a
- step :: k -> v -> v -> SF k v
- fromList :: Ord k => [(Bound k, v)] -> v -> SF k v
- normalise :: Eq v => SF k v -> SF k v
- (!) :: Ord k => SF k v -> k -> v
- values :: SF k v -> [v]
- showSF :: (Show a, Show b) => SF a b -> String
- putSF :: (Show a, Show b) => SF a b -> IO ()
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]
Step function. Piecewise constant function, having finitely many pieces. See https://en.wikipedia.org/wiki/Step_function.
describes a piecewise constant function \(f : k \to v\):SF
(fromList [(Open
k1, v1), (Closed
k2, v2)]) v3 :: SF
k v
\[ f\,x = \begin{cases} v_1, \quad x < k_1 \newline v_2, \quad k_1 \le x \le k_2 \newline v_3, \quad k_2 < x \end{cases} \]
or as you would write in Haskell
f x | x < k1 = v1 | x <= k2 = v2 | otherwise = v3
Note: total-map package, which provides function with finite support.
Constructor is exposed as you cannot construct non-valid SF
.
Merging
You can use Applicative
instance to merge SF
.
>>>
putSF $ liftA2 (+) (step 0 0 1) (step 1 0 1)
\x -> if | x < 0 -> 0 | x < 1 -> 1 | otherwise -> 2
Following property holds, i.e. SF
and ordinary function Applicative
instances
are compatible (and !
is a homomorphism).
liftA2 f g h ! x == liftA2 f (g !) (h !) x
Recall that for ordinary functions
.liftA2
f g h x = f (g x) (h x)
Dense?
This dense variant is useful with dense ordered domains, e.g. Rational
.
Integer
is not dense, so you could use Data.Function.Step.Discrete variant instead.
>>>
let s = fromList [(Open 0, -1),(Closed 0, 0)] 1 :: SF Rational Int
>>>
putSF s
\x -> if | x < 0 % 1 -> -1 | x <= 0 % 1 -> 0 | otherwise -> 1
>>>
import Data.Ratio ((%))
>>>
map (s !) [-1, -0.5, 0, 0.5, 1]
[-1,-1,0,1,1]
Show2 SF Source # | |
Ord k => Monad (SF k) Source # | |
Functor (SF k) Source # | |
Ord k => Applicative (SF k) Source # |
|
Foldable (SF k) Source # | |
Traversable (SF k) Source # | |
Show k => Show1 (SF k) Source # | |
(Eq v, Eq k) => Eq (SF k v) Source # | |
(Ord v, Ord k) => Ord (SF k v) Source # | |
(Show k, Show v) => Show (SF k v) Source # | |
(Ord k, Semigroup v) => Semigroup (SF k v) Source # | Piecewise
|
(Ord k, Monoid v) => Monoid (SF k v) Source # | |
(Ord k, Arbitrary k, Arbitrary v) => Arbitrary (SF k v) Source # | |
(NFData k, NFData v) => NFData (SF k v) Source # | |
Bound operations
Construction
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 => [(Bound k, v)] -> v -> SF k v Source #
Create function from list of cases and default value.
>>>
let f = fromList [(Open 1,2),(Closed 3,4),(Open 4,5)] 6
>>>
putSF f
\x -> if | x < 1 -> 2 | x <= 3 -> 4 | x < 4 -> 5 | otherwise -> 6
>>>
map (f !) [0..10]
[2,4,4,4,6,6,6,6,6,6,6]