auto-0.4.0.0: Denotative, locally stateful programming DSL & platform

Copyright(c) Justin Le 2015
LicenseMIT
Maintainerjustin@jle.im
Stabilityunstable
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

Control.Auto.Blip.Internal

Description

This module exposes an "unsafe" interface for working with the internal representation of "blip streams". If you are programming at the logic level or the application level, you should thoroughly be able to avoid importing this, and should be happy with importing the Blip type from Control.Auto and blip stream manipulators from Control.Auto.Blip.

If, however, you are programming a framework, library, or backend, you might find it useful to manually create your own blip streams/sources. In this case, this module will be useful.

It is important, as with most of this library in general, to always keep in mind when you are programming at the "logic" level, and when you are programming at the "backend" level. If you can justify that you are at the backend level and not at the logic level of whatever you are programming, then this is useful.

Be sure, of course, that whatever blip streams you do manually construct and export preserve "Blip semantics", which is further defined in Control.Auto.Blip.

You have been warned!

Synopsis

Documentation

data Blip a Source

When used in the context of an input or output of an Auto, a Blip a represents a stream that occasionally, at "independent" or "discrete" points, emits a value of type a.

Contrast this to Interval, where things are meant to be "on" or "off" for contiguous chunks at a time; blip streams are "blippy", and Intervals are "chunky".

It's here mainly because it's a pretty useful abstraction in the context of the many combinators found in various modules of this library. If you think of an Auto m a (Blip b) as producing a "blip stream", then there are various combinators and functions that are specifically designed to manipulate blip streams.

For the purposes of the semantics of what Blip is supposed to represent, its constructors are hidden. (Almost) all of the various Blip combinators (and its very useful Functor instance) "preserve Blipness" --- one-at-a-time occurrences remain one-at-a-time under all of these combinators, and you should have enough so that direct access to the constructor is not needed.

If you are creating a framework, library, or backend, you might want to manually create blip stream-producing Autos for your users to access. In this case, you can import the constructors and useful internal (and, of course, semantically unsafe) functions from Control.Auto.Blip.Internal.

Constructors

NoBlip 
Blip !a 

Instances

Functor Blip 
Show a => Show (Blip a) 
Generic (Blip a) 
Semigroup a => Monoid (Blip a)

Merge two blip streams together; the result emits with either of the two merged streams emit. When both emit at the same time, emit the result of <>-ing the values together.

Serialize a => Serialize (Blip a) 
NFData a => NFData (Blip a) 
Semigroup a => Semigroup (Blip a)

Merge two blip streams together; the result emits with either of the two merged streams emit. When both emit at the same time, emit the result of <>-ing the values together.

Typeable (* -> *) Blip 
type Rep (Blip a) 

merge Source

Arguments

:: (a -> a -> a)

merging function

-> Blip a

first stream

-> Blip a

second stream

-> Blip a

merged stream

Merge two blip streams together; the result emits with either of the two merged streams emit. When both emit at the same time, emit the result of applying the given function on the two emitted values.

Note that this might be too strict for some purposes; see mergeL and mergeR for lazier alternatives.

merge' Source

Arguments

:: (a -> c)

function for first stream

-> (b -> c)

function for second stream

-> (a -> b -> c)

merging function

-> Blip a

first stream

-> Blip b

second stream

-> Blip c

merged stream

Slightly more powerful merge, but I can't imagine a situation where this power is necessary.

If only the first stream emits, emit with the first function applied to the value. If only the second stream emits, emit with the second function applied to the value. If both emit, then emit with the third function applied to both emitted values.

mergeL infixr 5 Source

Arguments

:: Blip a

first stream (higher priority)

-> Blip a

second stream

-> Blip a 

Merges two blip streams together into one, which emits either of the original blip streams emit. If both emit at the same time, the left (first) one is favored.

Lazy on the second stream if the first stream is emitting.

If we discount laziness, this is merge const.

mergeR infixl 5 Source

Arguments

:: Blip a

first stream

-> Blip a

second stream (higher priority)

-> Blip a 

Merges two blip streams together into one, which emits either of the original blip streams emit. If both emit at the same time, the right (second) one is favored.

Lazy on the first stream if the second stream is emitting.

If we discount laziness, this is merge (flip const).

blip Source

Arguments

:: b

default value

-> (a -> b)

function to apply on value

-> Blip a

Blip to deconstruct

-> b 

Deconstruct a Blip by giving a default result if the Blip is non-occuring and a function to apply on the contents, if the Blip is occuring.

Try not to use if possible, unless you are a framework developer. If you're just making an application, try to use the other various combinators in this library. It'll help you preserve the semantics of what it means to be Blippy.

Analogous to maybe from Prelude.