Hello Conal,<br><br>What you've done looks very much like the Regular datatype [1] in the rewriting library [2]. The rewriting library, as its name indicates, is very much targeted at rewriting. For a more complete library using a sum of products view (and without type synonyms), try the new release of EMGM [3].<br>
<br><br>Cheers,<br>Pedro<br><br>[1] <a href="http://hackage.haskell.org/packages/archive/rewriting/0.1/doc/html/Generics-Regular-Rewriting-Representations.html#t%3ARegular">http://hackage.haskell.org/packages/archive/rewriting/0.1/doc/html/Generics-Regular-Rewriting-Representations.html#t%3ARegular</a><br>
[2] <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/rewriting">http://hackage.haskell.org/cgi-bin/hackage-scripts/package/rewriting</a><br>[3] <a href="http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/EMGM">http://www.cs.uu.nl/wiki/bin/view/GenericProgramming/EMGM</a><br>
<br><div class="gmail_quote">2008/11/18 Conal Elliott <span dir="ltr"><<a href="mailto:conal@conal.net">conal@conal.net</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Is there a simple existing library that provides views of data types in terms of unit, product and sum?<br><br>Here's what I threw together for my own use. I used associated types, though functional dependencies would work as well.<br>
<br><span style="font-family: courier new,monospace;"> class HasView t where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> type View t</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> view :: t -> View t</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> unview :: View t -> t</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> -- View instances</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> instance HasView (Maybe a) where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> type View (Maybe a) = Either () a</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> view Nothing = (Left ())</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> view (Just a) = (Right a)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> unview (Left ()) = Nothing</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> unview (Right a) = (Just a)</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;"> instance HasView [a] where</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> type View [a] = Either () (a,[a])</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> view [] = (Left ())</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> view (a:as) = (Right (a,as))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> unview (Left ()) = []</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> unview (Right (a,as)) = (a:as)</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;"> onView2 :: (HasView a, HasView b, HasView c) =></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (View a -> View b -> View c)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> -> (a -> b -> c)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> onView2 op a b = unview (view a `op` view b)</span><br style="font-family: courier new,monospace;">
<br>Thanks, - Conal<br>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br>