<span style="font-family: courier new,monospace;">==============================================</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Extensible and Modular Generics for the Masses</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">==============================================</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Extensible and Modular Generics for the Masses (EMGM) is a library for generic programming in Haskell using type classes and a sum-of-products view.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">------------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Introduction</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">------------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">emgm-0.2 is the second major release of the EMGM library.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">A lot of work has been done since the initial release to build a solid set of functions that will allow you to derive the necessary declarations for using EMGM with your datatype. Thus, you don&#39;t have to write much code to get started.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">A great deal of documentation has also been added. There&#39;s a comprehensive new entry page for Generics.EMGM that should help one figure out what to do with this library. We plan to publish articles providing more examples as well.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">With these two improvements, you have no more excuses for not trying it out. Download EMGM and see what you can do, generically!</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">------------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">New Features</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">------------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Improvements over emgm-0.1 include:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Derive type representation using Template Haskell [1]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Major improvement in documentation with Haddock</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">* &nbsp;bimap function [2]</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">[1] Here is a snippet from the documentation that shows what you save when using TH over manual implementation.</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; {-# LANGUAGE TemplateHaskell #-}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; {-# LANGUAGE MultiParamTypeClasses #-}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; {-# LANGUAGE FlexibleContexts #-}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; {-# LANGUAGE FlexibleInstances #-}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; {-# LANGUAGE OverlappingInstances #-}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; {-# LANGUAGE UndecidableInstances #-}</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; module Example where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; import Generics.EMGM</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; data T a = C a Int</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; $(derive &#39;&#39;T)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">The $(derive &#39;&#39;T) declaration in the above example generates the following code:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">1. Constructor description declarations (1 per constructor)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; conC :: ConDescr</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; conC = ConDescr &quot;C&quot; 2 [] Nonfix</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">2. Embedding-projection pair declarations (1 per type)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; epT :: EP (T a) (a :*: Int)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; epT = EP fromT toT</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; &nbsp; where fromT (C v1 v2) = v1 :*: v2</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; &nbsp; &nbsp; &nbsp; &nbsp; toT (v1 :*: v2) = C v1 v2</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">3. Rep instance (1 per type)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; instance (Generic g, Rep g a, Rep g Int) =&gt; Rep g (T a) where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; &nbsp; rep = rtype epT (rcon conC (rprod rep rep))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">4. Higher arity instances if applicable (either FRep, FRep2, and FRep3 together, or BiFRep2)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; instance (Generic g) =&gt; FRep g T where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; &nbsp; frep ra = rtype epT (rcon conC (rprod ra rint))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">In this case, similar instances would be generated for FRep2 and FRep3.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">5. Function-specific instances (1 per type)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&gt; instance Rep (Collect Char) Char where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; &nbsp; rep = Collect (:[])</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">[2] EMGM has a new function bimap and its related representation type class BiFRep2:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&gt; bimap :: (BiFRep2 Map f) =&gt; (a -&gt; c) -&gt; (b -&gt; d) -&gt; f a b -&gt; f c d</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">With bimap, you can do the following in GHCi:</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">*Generics.EMGM Data.Char Prelude&gt; bimap ord chr (&#39;a&#39;,65)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(97,&#39;A&#39;)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">*Generics.EMGM Data.Char Prelude&gt; bimap (++&quot; So Long!&quot;) (const 42) (Right &quot;Earth&quot;)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Right 42</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-------------------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">General Information</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">-------------------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Visit the home page:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;<a href="http://www.cs.uu.nl/wiki/GenericProgramming/EMGM">http://www.cs.uu.nl/wiki/GenericProgramming/EMGM</a></span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">----------------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">General Features</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">----------------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">The primary features of EMGM include:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Datatype-generic programming using sum-of-product views</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Large collection of ready-to-use generic functions</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">* &nbsp;Included support for standard datatypes: lists, Maybe, tuples</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Easy to add support for new datatypes</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">* &nbsp;Type classes make writing new functions straightforward in a structurally inductive style</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Generic functions are extensible with ad-hoc cases for arbitrary datatypes</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">* &nbsp;Good performance of generic functions</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">The features of this distribution include:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;The API is thoroughly documented with Haddock</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Fully tested with QuickCheck and HUnit</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">* &nbsp;Program coverage ensures that all useful code has been touched by tests</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Tested on both Mac and Windows systems</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">------------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Requirements</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">------------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">EMGM has the following requirements:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;GHC 6.8.1 - It has been tested with versions 6.8.3 and 6.10.1</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Cabal library 1.2.1 - It has been tested with versions 1.2.4.0 and 1.6.0.1.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-----------------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Download &amp; Source</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">-----------------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Use caball-install:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;cabal install emgm</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Get the package:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/emgm">http://hackage.haskell.org/cgi-bin/hackage-scripts/package/emgm</a></span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Check out the current source with Subversion:</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;svn checkout <a href="https://svn.cs.uu.nl:12443/repos/dgp-haskell/EMGM/trunk">https://svn.cs.uu.nl:12443/repos/dgp-haskell/EMGM/trunk</a></span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Or view it online:</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; <a href="https://svn.cs.uu.nl:12443/viewvc/dgp-haskell/EMGM/trunk/">https://svn.cs.uu.nl:12443/viewvc/dgp-haskell/EMGM/trunk/</a></span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">--------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Examples</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">--------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Check out the examples:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;<a href="https://svn.cs.uu.nl:12443/viewvc/dgp-haskell/EMGM/trunk/examples/">https://svn.cs.uu.nl:12443/viewvc/dgp-haskell/EMGM/trunk/examples/</a></span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">--------------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Bugs &amp; Support</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">--------------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Report issues or request features:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; <a href="http://code.google.com/p/emgm/issues/list">http://code.google.com/p/emgm/issues/list</a></span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Discuss EMGM with the authors, maintainers, and other interested persons:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;<a href="http://www.haskell.org/mailman/listinfo/generics">http://www.haskell.org/mailman/listinfo/generics</a></span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-------</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Credits</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">-------</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">The research for EMGM originated with Ralf Hinze. It was extended with work by Bruno Oliveira and Andres Löh. More details of the library functionality were explored by Alexey Rodriguez. We are very grateful to all of these people for the foundation on which this library was built.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">The current authors and maintainers of EMGM are:</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">* &nbsp;Sean Leather</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;José Pedro Magalhães</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">* &nbsp;Alexey Rodriguez</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">* &nbsp;Andres Löh</span>