Copyright | (c) Hanzhong Xu, Meng Meng 2016, |
---|---|
License | MIT License |
Maintainer | hanzh.xu@gmail.com |
Stability | experimental |
Portability | portable |
Safe Haskell | Safe |
Language | Haskell2010 |
Arrowized functional state machines.
This module is inspired by Yampa and the paper Functional Reactive Programming, Continued* written by Henrik Nilsson, Antony Courtney and John Peterson.
- data Event a
- class SMFunctor f where
- newtype TF s a b = TF (s -> a -> (SM s a b, b))
- transSM2TF :: SM t (s, a) (s, b) -> TF s a b
- data SM s a b = SM (TF s a b) s
- newSM :: (s -> a -> (SM s a b, b)) -> s -> SM s a b
- simpleSM :: (s -> a -> (s, b)) -> s -> SM s a b
- tf :: SM s a b -> s -> a -> (SM s a b, b)
- st :: SM s a b -> s
- type SMH a b = SM () a b
- newSMH :: (() -> a -> (SMH a b, b)) -> SMH a b
- simpleSMH :: (s -> a -> (s, b)) -> s -> SMH a b
- hideStorage :: SM s a b -> SMH a b
- buildSrc :: SM s a a -> [a]
- simpleSrc :: SM s () a -> [a]
- constSM :: b -> SM () a b
- idSM :: SM () a a
- delaySM :: a -> SM a a a
- arrSM :: (a -> b) -> SM () a b
- foldlSM :: (s -> a -> s) -> s -> SM s a s
- foldlDelaySM :: (s -> a -> s) -> s -> SM s a s
- composeSM :: SM s1 b c -> SM s0 a b -> SM (s0, s1) a c
- (>>>>) :: SM s0 a b -> SM s1 b c -> SM (s0, s1) a c
- (<<<<) :: SM s1 b c -> SM s0 a b -> SM (s0, s1) a c
- (^>>>) :: (a -> b) -> SM s b c -> SM s a c
- (>>>^) :: SM s a b -> (b -> c) -> SM s a c
- (^<<<) :: (b -> c) -> SM s a b -> SM s a c
- (<<<^) :: SM s b c -> (a -> b) -> SM s a c
- firstSM :: SM s a b -> SM s (a, c) (b, c)
- secondSM :: SM s a b -> SM s (c, a) (c, b)
- (****) :: SM s0 a b -> SM s1 c d -> SM (s0, s1) (a, c) (b, d)
- (&&&&) :: SM s0 a b -> SM s1 a c -> SM (s0, s1) a (b, c)
- leftSM :: SM s a b -> SM s (Either a c) (Either b c)
- rightSM :: SM s a b -> SM s (Either c a) (Either c b)
- (++++) :: SM s0 a b -> SM s1 c d -> SM (s0, s1) (Either a c) (Either b d)
- (||||) :: SM s0 a c -> SM s1 b c -> SM (s0, s1) (Either a b) c
- loopSM :: SM s (a, c) (b, c) -> SM s a b
- absorb :: (a1 -> a0) -> (a1 -> b0 -> b1) -> SM s a0 b0 -> SM s a1 b1
- merge :: (a2 -> (a0, a1)) -> (a2 -> b0 -> b1 -> b2) -> SM s0 a0 b0 -> SM s1 a1 b1 -> SM (s0, s1) a2 b2
- execSM :: SM s a b -> SM s [a] [b]
- concatSM :: SM s a [[b]] -> SM s a [b]
- step :: SM s a b -> a -> (SM s a b, b)
- exec :: SM s a b -> [a] -> (SM s a b, [b])
Documentation
Event
type, there are 4 different events: event a, no event, error event string and exit event.
The TF
type
TF
is a type representing a transition function.
s: storage, a: input, b: output
Let's explain more about TF
. When a state gets an input a,
it should do three things base on the storage and input:
find the next state, update storage and output b.
That's why it looks like this:
(storage -> a -> (SM newState newStorage, b))
type TF storage input output = (storage -> input -> (SM storage input output, output))
Also, it is an instance of Arrow, it represents a machine without initial storage.
composing two TF represents that two SM shares the same storage
transSM2TF :: SM t (s, a) (s, b) -> TF s a b Source #
transform `SM t (s, a) (s, b)` to `TF s a b`
The SM
type
SM
is a type representing a state machine.
(TF s a b): initial state(transition function), s: initial storage
SM storage input output = SM (TF storage input output) storage
SM Constructors
The SMH
type - SM with hidden storage
type SMH a b = SM () a b Source #
SMH
is the type of the state machine with hidden or no storage.
It is the same type with
Circuit a b = Circuit (a -> Circuit a b, b)
hideStorage :: SM s a b -> SMH a b Source #
hide the Storage type in the transition function.
Source Constructors
buildSrc :: SM s a a -> [a] Source #
Source There are two kinds of source. First one is using the output of `SM s a a` as its input, then it becomes a perpetual motion, :) Second one is a SM which ignore its input, and output something based on its storage. The second one is easier to understand and use.
build a source, for example: buildSrc $ foldlDelaySM (const (+1)) 0 [0..] buildSrc $ foldlDelaySM (+) 1 [1, 2, 4, 8, ...]
simpleSrc :: SM s () a -> [a] Source #
build a simple source, which ignore the inputs fibsSM :: SM (Int, Int) () Int fibsSM = simpleSM ((a, b) () -> ((b, a+b), a)) (0, 1) take 10 $ simpleSrc fibsSM [0,1,1,2,3, ...]simpleSrc :: SM s () a -> [a]
Basic State Machines
delaySM :: a -> SM a a a Source #
delay the input with given value. delaySM = foldlDelaySM (const id)
foldlDelaySM :: (s -> a -> s) -> s -> SM s a s Source #
the difference from foldlSM is it output the storage first.
Basic SM functions
composeSM :: SM s1 b c -> SM s0 a b -> SM (s0, s1) a c Source #
compose two SM and merge their storage.
merge :: (a2 -> (a0, a1)) -> (a2 -> b0 -> b1 -> b2) -> SM s0 a0 b0 -> SM s1 a1 b1 -> SM (s0, s1) a2 b2 Source #
High order Machines
execSM :: SM s a b -> SM s [a] [b] Source #
converts SM a b -> SM [a] [b], it is very useful to compose SM a [b] and SM b c to SM a [c].