Difference between revisions of "TypeCompose"

From HaskellWiki
Jump to navigation Jump to search
m (→‎Data-driven computation: fixed name bug)
m (→‎Data-driven computation: "Compose" --> "O")
Line 19: Line 19:
   
 
<haskell>
 
<haskell>
type DataDrivenG news src = Compose ((,) news) src
+
type DataDrivenG news src = (,) news `O` src
 
</haskell>
 
</haskell>
   
Thanks to properties of [http://darcs.haskell.org/packages/TypeCompose/doc/html/Control-Compose.html#t%3ACompose <hask>Compose</hask>], when <hask>news</hask> is a [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#t%3AMonoid monoid] and <hask>src</hask> is an [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t%3AApplicative applicative functor], <hask>DataDriven news src</hask> is an applicative functor also. The applicative property is very convenient for composition.
+
Thanks to properties of type composition ([http://darcs.haskell.org/packages/TypeCompose/doc/html/Control-Compose.html#t%3AO <hask>O</hask>]), when <hask>news</hask> is a [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#t%3AMonoid monoid] and <hask>src</hask> is an [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#t%3AApplicative applicative functor], <hask>DataDriven news src</hask> is an applicative functor also. The applicative property is very convenient for composition.
   
 
To see how our simple definitions manage data-driven computations, expand the <hask>Applicative</hask> instances of <hask>Compose</hask> and <hask>(,) a</hask>:
 
To see how our simple definitions manage data-driven computations, expand the <hask>Applicative</hask> instances of <hask>Compose</hask> and <hask>(,) a</hask>:

Revision as of 22:46, 31 July 2007

Abstract

TypeCompose provides some classes & instances for forms of type composition. It also includes a very simple implementation of data-driven computation.

TypeCompose is used in Phooey, a functional GUI library.

Type composition

For now, see the Haddock docs and source code.

Data-driven computation

The representation of data-driven computations is quite simple and general. They have a news publisher (news) and a source of new values (src). Clients interested in the value subscribe to news and extract a new value from src when notified that the value may have changed.

type DataDrivenG news src = (,) news `O` src

Thanks to properties of type composition (O), when news is a monoid and src is an applicative functor, DataDriven news src is an applicative functor also. The applicative property is very convenient for composition.

To see how our simple definitions manage data-driven computations, expand the Applicative instances of Compose and (,) a:

instance (Applicative src) => Applicative (DataDrivenG news src) where
  pure a = Comp (mempty, pure a)
  Comp (newsf,srcf) <*> Comp (newsx, srcx) =
    Comp (newsf `mappend` newsx) (srcf <*> srcx)

The idea here is that mempty is publisher that never has news to report, while mappend combines publishers into one that reports all the news of either. Thus DataDrivenG accumulates event sources as it composes, as well as delegating to whatever composition is done by src.

Specializing

Specializing, introduce types of "updaters" (actions), "sinks" (consumers) of values, and "news publishers" (somewhere to register updaters to be executed when events occur).

type Updater src = src ()
type Sink src a  = a -> Updater src
type News src    = Sink src (Updater src)

And specialize DataDriven for news publishers:

type DataDriven src = DataDrivenG (News src) src

For instance, the "Source" types used in Phooey are defined simply as

type Source = DataDriven IO

Note that News src is a monoid when src () is. In particular, given any applicative functor f, we can supply the following:

-- Standard instance: Applicative functor applied to monoid
instance Monoid a => Monoid (f a) where { mempty = pure mempty; mappend = (*>) }

Note that () is a monoid. See an example in the Control.Instances module.