Module

Data.Machine.Mealy

Package
purescript-machines
Repository
purescript-contrib/purescript-machines

This module provides the building blocks required to create finite state machines.

#MealyT Source

newtype MealyT :: (Type -> Type) -> Type -> Type -> Typenewtype MealyT f i o

Mealy is a finite state machine, where:

  • f is the effect under which we evaluate,
  • i is the input type and
  • o is the output type.

Instances

#runMealyT Source

runMealyT :: forall f i o. MealyT f i o -> i -> f (Step f i o)

#hoistMealyT Source

hoistMealyT :: forall f g i. Functor g => (f ~> g) -> (MealyT f i) ~> (MealyT g i)

Transforms a Mealy machine running in the context of f into one running in g, given a natural transformation from f to g.

#Step Source

data Step :: (Type -> Type) -> Type -> Type -> Typedata Step f i o

Step is the core for running machines. Machines can either stop via the Halt constructor, or emit a value and recursively construct the rest of the machine.

Constructors

#Source Source

type Source :: (Type -> Type) -> Type -> Typetype Source f o = MealyT f Unit o

Sources are 'initial nodes' in machines. They allow for data to be generated.

#Sink Source

type Sink :: (Type -> Type) -> Type -> Typetype Sink f i = MealyT f i Unit

Sinks are 'terminator nodes' in machines. They allow for an effectful computation to be executed on the inputs.

#source Source

source :: forall f o. Functor f => f o -> Source f o

Wrap an effectful value into a source. The effect will be repeated indefinitely.

For example, generating ten instances of the value 1:

take 10 $ source (pure 1)

#sink Source

sink :: forall f i. Functor f => (i -> f Unit) -> Sink f i

Construct a machine which executes an effectful computation on its inputs.

For example, logging could be used as a sink:

take 10 $ source (pure 1) >>> sink logShow

#stepMealy Source

stepMealy :: forall f i o. i -> MealyT f i o -> f (Step f i o)

Execute (unroll) a single step on a machine.

#runMealy Source

runMealy :: forall f. Monad f => MealyT f Unit Unit -> f Unit

Run a machine as an effectful computatation.

For example:

runMealy $ take 10 $ source (pure 1) >>> sink logShow

#pureMealy Source

pureMealy :: forall f i o. Applicative f => (i -> Step f i o) -> MealyT f i o

Wrap a pure function into a machine. The function can either terminate via Halt, or Emit a value and then decide whether to Halt, continue with a different function, or (usually) wrap itself via pureMealy recursively.

For example, we can Halt on zero:

haltOn0 :: forall f. Applicative f => MealyT f Int Int
haltOn0 = pureMealy go
  where
    go 0 = Halt
    go n = Emit n (pureMealy haltOn0)

#mealy Source

mealy :: forall f i o. (i -> f (Step f i o)) -> MealyT f i o

Wrap an effectful function into a machine. See pureMealy for an example using pure functions.

#halt Source

halt :: forall f i o. Applicative f => MealyT f i o

A machine which halts for any input.

#take Source

take :: forall f i o. Applicative f => Int -> MealyT f i o -> MealyT f i o

Limit the number of outputs of a machine. After using up the n allotted outputs, the machine will halt.

#drop Source

drop :: forall f i o. Monad f => Int -> MealyT f i o -> MealyT f i o

Skip a number of outputs for a machine.

#loop Source

loop :: forall f i o. Monad f => MealyT f i o -> MealyT f i o

Loop a machine forever.

#toUnfoldable Source

toUnfoldable :: forall f g i o. Unfoldable g => Comonad f => i -> MealyT f i o -> g o

Extract all the outputs of a machine, given some input.

#zipWith Source

zipWith :: forall f i a b c. Apply f => (a -> b -> c) -> MealyT f i a -> MealyT f i b -> MealyT f i c

Zip two machines together under some function f.

#scanl Source

scanl :: forall f i a b. Functor f => (b -> a -> b) -> b -> MealyT f i a -> MealyT f i b

Accumulate the outputs of a machine into a new machine.

#collect Source

collect :: forall f i o. Functor f => MealyT f i o -> MealyT f i (List o)

Accumulates the outputs of a machine as a List.

#singleton Source

singleton :: forall f i o. Applicative f => o -> MealyT f i o

Creates a machine which emits a single value before halting.

#fromMaybe Source

fromMaybe :: forall f i o. Applicative f => Maybe o -> MealyT f i o

Creates a machine which either emits a single value before halting (for Just), or just halts (in the case of Nothing).

#fromArray Source

fromArray :: forall f i o. Monad f => Array o -> MealyT f i o

Creates a machine which emits all the values of the array before halting.

#msplit Source

msplit :: forall f i o. Applicative f => MealyT f i o -> MealyT f i (Maybe (Tuple o (MealyT f i o)))

Unwrap a machine such that its output is either Nothing in case it would halt, or Just the output value and the next computation.

#interleave Source

interleave :: forall f i o. Monad f => MealyT f i o -> MealyT f i o -> MealyT f i o

Interleaves the values of two machines with matching inputs and outputs.

#once Source

once :: forall f s a. Applicative f => MealyT f s a -> MealyT f s a

Takes a single output from a machine.

#when Source

when :: forall f i a b. Monad f => MealyT f i a -> (a -> MealyT f i b) -> MealyT f i b

Given a machine and a continuation, it will pass outputs from the machine to the continuation as long as possible until one of them halts.

#ifte Source

ifte :: forall f i a b. Monad f => MealyT f i a -> (a -> MealyT f i b) -> MealyT f i b -> MealyT f i b

If then else: given a machine producing a, a continuation f, and a machine producing b, generate a machine which will grab outputs from the first machine and pass them over to the continuation as long as neither halts. Once the process halts, the second (b) machine is returned.

#wrapEffect Source

wrapEffect :: forall f i o. Applicative f => f o -> MealyT f i o

Creates a machine which wraps an effectful computation and ignores its input.