# Difference between revisions of "TypeCompose"

m (→Type composition) |
m |
||

(20 intermediate revisions by 4 users not shown) | |||

Line 1: | Line 1: | ||

+ | [[Category:Applicative Functor]] |
||

+ | [[Category:Libraries]] |
||

+ | [[Category:Packages]] |
||

+ | [[Category:Type-level programming]] |
||

+ | |||

== Abstract == |
== Abstract == |
||

− | '''TypeCompose''' provides some classes & instances for forms of type composition |
+ | '''TypeCompose''' provides some classes & instances for forms of type composition, as well as some modules that haven't found another home. |

− | * Read [http://darcs.haskell.org/packages/TypeCompose/doc/html the Haddock docs] (with source code, additional examples, and Comment/Talk links). |
||

+ | Besides this wiki page, here are more ways to find out about TypeCompose: |
||

− | * Get the code repository: '''<tt>darcs get http://darcs.haskell.org/packages/TypeCompose</tt>''', or |
||

+ | * Visit the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/TypeCompose Hackage page] for library documentation and to download & install. |
||

− | * Grab a [http://darcs.haskell.org/packages/TypeCompose/dist distribution tarball]. |
||

+ | * Or install with <tt>cabal install TypeCompose</tt>. |
||

− | * See the [http://darcs.haskell.org/packages/TypeCompose/CHANGES version changes]. |
||

+ | * Get the code repository: <tt>git clone git@github.com:conal/TypeCompose.git</tt>. |
||

− | |||

+ | <!--* See the [[TypeCompose/Versions| version history]].--> |
||

− | TypeCompose is used in [[Phooey]], a functional GUI library. |
||

== Type composition == |
== Type composition == |
||

− | For now, see the [http://darcs.haskell.org/packages/TypeCompose/doc/html/Control-Compose.html Haddock docs] and [http://darcs.haskell.org/packages/TypeCompose/doc/html/src.Control.Compose.hs.html source code]. |
||

+ | The <hask>Control.Compose</hask> module includes |
||

+ | * Various type compositions (unary/unary, binary/unary, etc). Most are from [http://www.soi.city.ac.uk/~ross/papers/Applicative.html Applicative Programming with Effects]. In particular, <hask>g `O` f</hask> composes functors in to functors and applicative functors (AFs) into AFs. (In contrast, monads do not in general compose.) Composition makes AF-based programming simple and elegant, partly because we don't need an AF counterpart to monad transformers. |
||

+ | * Cofunctors (contravariant functors). Great for "consumer" types, just as functors suit "producer" (container) types. There are several composition options. |
||

+ | * Type argument flip. Handy for cofunctors: use <hask>Flip (->) o</hask>, for <hask>(-> o)</hask>. |
||

+ | * Constructor in pairs: <hask>(f a, g a)</hask>. |
||

+ | * Constructor in arrows/functions: <hask>f a ~> g a</hask>. |
||

+ | |||

+ | == Other features == |
||

+ | |||

+ | === Composable bijections === |
||

+ | |||

+ | Given all the type constructors and compositions of them, I found myself writing some pretty awkward code to wrap & unwrap through multiple layers. Composable bijections help a lot. |
||

− | == Data-driven computation == |
||

+ | The <hask>Data.Bijection</hask> module is inspired by [http://citeseer.ist.psu.edu/alimarine05there.html There and Back Again: Arrows for Invertible Programming], though done here in a less general setting. |
||

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

+ | === Pair- & function-like types === |
||

− | <haskell> |
||

+ | The <hask>Data.Zip</hask> and <hask>Data.Lambda</hask> patterns emerged while working on [[DeepArrow]] and [[Eros]]. <hask>Data.Zip</hask> generalizes <hask>zip</hask> and <hask>unzip</hask> from <hask>[]</hask> to other functors. It also provides variants of type <hask>f a -> f (a,b)</hask> and <hask>f a -> f (a,b)</hask>. <hask>Data.Lambda</hask> is similar with classes for lambda-like constructions. |
||

− | type DataDrivenG news src = Compose ((,) news) src |
||

− | </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 applicative functor, <hask>DataDriven news src</hask> is an applicative functor also. The applicative property is very convenient for composition. |
||

+ | For example uses of <hask>Pair</hask> and <hask>Lambda</hask>, see [[TV]] and [[Eros]]. |
||

− | To see how our simple definitions manage data-driven computations, expand the <hask>Applicative</hask> instances of <hask>Compose</hask> and <hask>(,) a</hask>: |
||

+ | === References === |
||

− | <haskell> |
||

− | instance (Applicative src) => Applicative (DataDrivenG news src) where |
||

− | pure a = Comp (mempty, pure a) |
||

− | Comp (newsf,srcf) <*> Comp (newsx, srcx) = |
||

− | Comp (newsf `mappend` newsx) (getf <*> getx) |
||

− | </haskell> |
||

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

+ | Monads with references. Direct rip-off from [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.23.145 Global Variables in Haskell]. |
||

− | === |
+ | === Titling === |

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

+ | For giving titles to things. I know it sounds kind of random. More useful than I first thought. Used in [[Phooey]], [[TV]], and [[Eros]]. |
||

− | <haskell> |
||

+ | === Partial values === |
||

− | type Sink src a = a -> Updater src |
||

− | type Updater src = src () |
||

− | type News src = Sink src (Updater src) |
||

− | </haskell> |
||

− | And specialize <hask>DataDriven</hask> for news publishers: |
||

+ | A monoid of partial values. See the [http://conal.net/blog/posts/a-type-for-partial-values/ teaser] and [http://conal.net/blog/posts/implementing-a-type-for-partial-values/ solution] blog |
||

− | <haskell> |
||

+ | posts. |
||

− | type DataDriven src = DataDrivenG (News src) src |
||

− | </haskell> |
||

− | For instance, the "Source" types used in [[Phooey]] are defined simply as |
||

+ | === Context-dependent monoids === |
||

− | <haskell> |
||

− | type Source = DataDriven IO |
||

− | </haskell> |
||

− | Note that <hask>News src</hask> is a [http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html#t%3AMonoid monoid] when <hask>src ()</hask> is. In particular, given any applicative functor <hask>f</hask>, we can supply the following: |
||

+ | Bit of an oddball also. <hask>Data.CxMonoid</hask> defines a sort of meta-monoid, that can be supplied dynamically with choices of <hask>mempty</hask> and <hask>mappend</hask>. Used in [[Phooey]] (starting with version 1.3) so that layout could be a monoid but still vary in style. |
||

− | <haskell> |
||

− | -- Standard instance: Applicative functor applied to monoid |
||

− | instance Monoid a => Monoid (f a) where { mempty = pure mempty; mappend = (*>) } |
||

− | </haskell> |
||

− | Note that <hask>()</hask> is a monoid. See an example in the [http://darcs.haskell.org/packages/TypeCompose/doc/html/src.Control.Instances.hs.html <hask>Control.Instances</hask> module]. |

## Latest revision as of 22:44, 29 June 2021

## Contents

## Abstract

**TypeCompose** provides some classes & instances for forms of type composition, as well as some modules that haven't found another home.

Besides this wiki page, here are more ways to find out about TypeCompose:

- Visit the Hackage page for library documentation and to download & install.
- Or install with
`cabal install TypeCompose`. - Get the code repository:
`git clone git@github.com:conal/TypeCompose.git`.

## Type composition

The `Control.Compose`

module includes

- Various type compositions (unary/unary, binary/unary, etc). Most are from Applicative Programming with Effects. In particular,
`g `O` f`

composes functors in to functors and applicative functors (AFs) into AFs. (In contrast, monads do not in general compose.) Composition makes AF-based programming simple and elegant, partly because we don't need an AF counterpart to monad transformers. - Cofunctors (contravariant functors). Great for "consumer" types, just as functors suit "producer" (container) types. There are several composition options.
- Type argument flip. Handy for cofunctors: use
`Flip (->) o`

, for`(-> o)`

. - Constructor in pairs:
`(f a, g a)`

. - Constructor in arrows/functions:
`f a ~> g a`

.

## Other features

### Composable bijections

Given all the type constructors and compositions of them, I found myself writing some pretty awkward code to wrap & unwrap through multiple layers. Composable bijections help a lot.

The `Data.Bijection`

module is inspired by There and Back Again: Arrows for Invertible Programming, though done here in a less general setting.

### Pair- & function-like types

The `Data.Zip`

and `Data.Lambda`

patterns emerged while working on DeepArrow and Eros. `Data.Zip`

generalizes `zip`

and `unzip`

from `[]`

to other functors. It also provides variants of type `f a -> f (a,b)`

and `f a -> f (a,b)`

. `Data.Lambda`

is similar with classes for lambda-like constructions.

For example uses of `Pair`

and `Lambda`

, see TV and Eros.

### References

Monads with references. Direct rip-off from Global Variables in Haskell.

### Titling

For giving titles to things. I know it sounds kind of random. More useful than I first thought. Used in Phooey, TV, and Eros.

### Partial values

A monoid of partial values. See the teaser and solution blog posts.

### Context-dependent monoids

Bit of an oddball also. `Data.CxMonoid`

defines a sort of meta-monoid, that can be supplied dynamically with choices of `mempty`

and `mappend`

. Used in Phooey (starting with version 1.3) so that layout could be a monoid but still vary in style.