<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tupil Code Blog &#187; abstraction</title>
	<atom:link href="http://blog.tupil.com/tag/abstraction/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tupil.com</link>
	<description>(Get up early, code often)</description>
	<lastBuildDate>Fri, 27 Aug 2010 10:50:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Formlets in Haskell</title>
		<link>http://blog.tupil.com/formlets-in-haskell/</link>
		<comments>http://blog.tupil.com/formlets-in-haskell/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 13:00:44 +0000</pubDate>
		<dc:creator>Chris Eidhof</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[abstraction]]></category>
		<category><![CDATA[applicative]]></category>
		<category><![CDATA[formlets]]></category>
		<category><![CDATA[HAppS]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=25</guid>
		<description><![CDATA[One of the most low-level parts of web development is building forms. You need to code to both build forms and handle them, and manually sync that code to make sure the names match up. In this post, we will use formlets and HAppS-Server to solve those problems. Formlets are a way to compose parts [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most low-level parts of web development is building forms. You need to code to both build forms and handle them, and manually sync that code to make sure the names match up. In this post, we will use <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/formlets">formlets</a> and <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HAppS-Server">HAppS-Server</a> to solve those problems. Formlets are a way to compose parts of a form into a complete form, without having to worry about names, types and validations.</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> <span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span>
 <span style="color: #06c; font-weight: bold;">import</span> HAppS<span style="color: #339933; font-weight: bold;">.</span>Server
 <span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Applicative
 <span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Applicative<span style="color: #339933; font-weight: bold;">.</span>Error
 <span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Applicative<span style="color: #339933; font-weight: bold;">.</span>State
 <span style="color: #06c; font-weight: bold;">import</span> Text<span style="color: #339933; font-weight: bold;">.</span>Formlets
 <span style="color: #06c; font-weight: bold;">import</span> Text<span style="color: #339933; font-weight: bold;">.</span>XHtml<span style="color: #339933; font-weight: bold;">.</span>Strict <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">+++</span><span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">&lt;&lt;</span><span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">!</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
 <span style="color: #06c; font-weight: bold;">import</span> <span style="color: #06c; font-weight: bold;">qualified</span> Text<span style="color: #339933; font-weight: bold;">.</span>XHtml<span style="color: #339933; font-weight: bold;">.</span>Strict <span style="color: #06c; font-weight: bold;">as</span> X
 <span style="color: #06c; font-weight: bold;">import</span> <span style="color: #06c; font-weight: bold;">qualified</span> Data<span style="color: #339933; font-weight: bold;">.</span>Map <span style="color: #06c; font-weight: bold;">as</span> M</pre></div></div>

<p>First of all, we are going to build a form that accepts a date (consisting of two parts: a month and a day). Our datatype reflects this:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> <span style="color: #06c; font-weight: bold;">data</span> Date <span style="color: #339933; font-weight: bold;">=</span> Date <span style="color: green;">&#123;</span>month <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Integer</span><span style="color: #339933; font-weight: bold;">,</span> day <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Integer</span><span style="color: green;">&#125;</span> <span style="color: #06c; font-weight: bold;">deriving</span> <span style="color: #cccc00; font-weight: bold;">Show</span></pre></div></div>

<p>We want to prevent the user from entering weird dates, so</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> validDate <span style="color: #339933; font-weight: bold;">::</span> Date <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">Bool</span>
 validDate <span style="color: green;">&#40;</span>Date m d<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> m `<span style="font-weight: bold;">elem</span>` <span style="color: green;">&#91;</span>1<span style="color: #339933; font-weight: bold;">..</span>12<span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">&amp;&amp;</span> d `<span style="font-weight: bold;">elem</span>` <span style="color: green;">&#91;</span>1<span style="color: #339933; font-weight: bold;">..</span>31<span style="color: green;">&#93;</span></pre></div></div>

<p>Now we are going to write a FailingForm that reads two integers, and uses them to create a real Date. Using applicative style, we can nicely express this:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> dateComponent <span style="color: #339933; font-weight: bold;">::</span> FailingForm Date
 dateComponent <span style="color: #339933; font-weight: bold;">=</span> Date <span style="color: #339933; font-weight: bold;">&lt;$&gt;</span> inputIntegerF <span style="color: green;">&#40;</span>Just <span style="color: red;">1</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">&lt;*&gt;</span> inputIntegerF <span style="color: green;">&#40;</span>Just <span style="color: red;">16</span><span style="color: green;">&#41;</span></pre></div></div>

<p>We can now combine dateComponent and validDate to create a validating Date component:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> dateFull <span style="color: #339933; font-weight: bold;">::</span> FailingForm Date
 dateFull   <span style="color: #339933; font-weight: bold;">=</span> dateComponent `check` ensure validDate <span style="">&quot;This is not a valid date&quot;</span></pre></div></div>

<p>Finally, if we use some helper functions we can create a ServerPart, which is everything HAppS needs in order to run:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> handleDate <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#91;</span>ServerPart Response<span style="color: green;">&#93;</span>
 handleDate <span style="color: #339933; font-weight: bold;">=</span> withForm <span style="">&quot;date&quot;</span> dateFull showErrorsInline <span style="color: green;">&#40;</span>\d <span style="color: #339933; font-weight: bold;">-&gt;</span> okHtml <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">show</span> d<span style="color: green;">&#41;</span></pre></div></div>

<p>This will show a form, and if you press &#8220;Submit&#8221;, it will make sure all validations pass, and show you the value. If the form doesn&#8217;t get validated, it will show a list of errors, and you can change your previously entered values.</p>
<p>To demonstrate the compositionality of formlets, we will create a User datatype, and use the date-formlet to let the user enter a birthDate:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> <span style="color: #06c; font-weight: bold;">data</span> User <span style="color: #339933; font-weight: bold;">=</span> User <span style="color: green;">&#123;</span>name <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><span style="color: #339933; font-weight: bold;">,</span> password <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><span style="color: #339933; font-weight: bold;">,</span> birthdate <span style="color: #339933; font-weight: bold;">::</span> Date<span style="color: green;">&#125;</span> <span style="color: #06c; font-weight: bold;">deriving</span> <span style="color: #cccc00; font-weight: bold;">Show</span>
&nbsp;
 userFull <span style="color: #339933; font-weight: bold;">::</span> FailingForm User
 userFull <span style="color: #339933; font-weight: bold;">=</span> User <span style="color: #339933; font-weight: bold;">&lt;$&gt;</span> inputF Nothing <span style="color: #339933; font-weight: bold;">&lt;*&gt;</span> passwordF Nothing <span style="color: #339933; font-weight: bold;">&lt;*&gt;</span> dateFull</pre></div></div>

<p>And that&#8217;s all there is to it! We now have user form that asks for a name, a password and a birthdate. We can use the withForm function again to handle the GET and POST:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> handleUser <span style="color: #339933; font-weight: bold;">=</span> withForm <span style="">&quot;user&quot;</span> userFull showErrorsInline <span style="color: green;">&#40;</span>\u <span style="color: #339933; font-weight: bold;">-&gt;</span> okHtml <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">show</span> u<span style="color: green;">&#41;</span></pre></div></div>

<p>Finally, here are all the helper functions we used:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> withForm <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> FailingForm a <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>Html <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span>ServerPart Response<span style="color: green;">&#93;</span>
 withForm name frm handleErrors handleOk <span style="color: #339933; font-weight: bold;">=</span> 
   <span style="color: green;">&#91;</span>dir name 
      <span style="color: green;">&#91;</span> method GET           <span style="color: #339933; font-weight: bold;">$</span> okHtml <span style="color: #339933; font-weight: bold;">$</span> createForm <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> frm
      <span style="color: #339933; font-weight: bold;">,</span> withDataFn lookPairs <span style="color: #339933; font-weight: bold;">$</span> \d <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span>method POST <span style="color: #339933; font-weight: bold;">$</span> handleOk' d<span style="color: green;">&#93;</span>
      <span style="color: green;">&#93;</span>
   <span style="color: green;">&#93;</span>
   <span style="color: #06c; font-weight: bold;">where</span> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>extractor<span style="color: #339933; font-weight: bold;">,</span> html<span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> endState<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> runFormState <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> frm <span style="color: red;">0</span>
         handleOk' d <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">case</span> extractor d <span style="color: #06c; font-weight: bold;">of</span>
                         Failure faults <span style="color: #339933; font-weight: bold;">-&gt;</span> handleErrors <span style="color: green;">&#40;</span>createForm d frm<span style="color: green;">&#41;</span> faults
                         Success s      <span style="color: #339933; font-weight: bold;">-&gt;</span> handleOk s
&nbsp;
 showErrorsInline <span style="color: #339933; font-weight: bold;">::</span> X<span style="color: #339933; font-weight: bold;">.</span>Html <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response
 showErrorsInline renderedForm errors <span style="color: #339933; font-weight: bold;">=</span>
   okHtml <span style="color: #339933; font-weight: bold;">$</span> X<span style="color: #339933; font-weight: bold;">.</span>toHtml <span style="color: green;">&#40;</span><span style="font-weight: bold;">show</span> errors<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+++</span> renderedForm
&nbsp;
 createForm <span style="color: #339933; font-weight: bold;">::</span> Env <span style="color: #339933; font-weight: bold;">-&gt;</span> FailingForm a <span style="color: #339933; font-weight: bold;">-&gt;</span> X<span style="color: #339933; font-weight: bold;">.</span>Html
 createForm env frm <span style="color: #339933; font-weight: bold;">=</span>
   X<span style="color: #339933; font-weight: bold;">.</span>form <span style="color: #339933; font-weight: bold;">!</span> <span style="color: green;">&#91;</span>X<span style="color: #339933; font-weight: bold;">.</span>method <span style="">&quot;POST&quot;</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">&lt;&lt;</span> <span style="color: green;">&#40;</span>xml <span style="color: #339933; font-weight: bold;">+++</span> X<span style="color: #339933; font-weight: bold;">.</span>submit <span style="">&quot;submit&quot;</span> <span style="">&quot;Submit&quot;</span><span style="color: green;">&#41;</span>
    <span style="color: #06c; font-weight: bold;">where</span> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>extractor<span style="color: #339933; font-weight: bold;">,</span> xml<span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> endState<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> runFormState env frm <span style="color: red;">0</span>
&nbsp;
 okHtml <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>HTML a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> a <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response
 okHtml content <span style="color: #339933; font-weight: bold;">=</span> ok <span style="color: #339933; font-weight: bold;">$</span> toResponse <span style="color: #339933; font-weight: bold;">$</span> htmlPage <span style="color: #339933; font-weight: bold;">$</span> content
&nbsp;
 htmlPage <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>HTML a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> a <span style="color: #339933; font-weight: bold;">-&gt;</span> X<span style="color: #339933; font-weight: bold;">.</span>Html
 htmlPage content <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>header  <span style="color: #339933; font-weight: bold;">&lt;&lt;</span>  <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>thetitle <span style="color: #339933; font-weight: bold;">&lt;&lt;</span> <span style="">&quot;Testing forms&quot;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+++</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>body    <span style="color: #339933; font-weight: bold;">&lt;&lt;</span>  content<span style="color: green;">&#41;</span>
&nbsp;
 main <span style="color: #339933; font-weight: bold;">=</span> simpleHTTP <span style="color: green;">&#40;</span>nullConf <span style="color: green;">&#123;</span>port <span style="color: #339933; font-weight: bold;">=</span> <span style="color: red;">5000</span><span style="color: green;">&#125;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>handleDate <span style="color: #339933; font-weight: bold;">++</span> handleUser<span style="color: green;">&#41;</span></pre></div></div>

<p>For the full code, see <a href='http://blog.tupil.com/wp-content/uploads/2008/07/main.lhs'>Main.lhs</a>. Make sure you have installed HAppS-Server and formlets from hackage. Enjoy!</p>
<p><b>Update</b>: There is now a wiki page on <a href="http://haskell.org/haskellwiki/Formlets">Formlets</a> which we try to keep up to date with examples that compile with the latest version. The example above only works with an old version of formlets.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/formlets-in-haskell/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
