<?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>Farblondzshet in Code &#187; Haskell</title>
	<atom:link href="http://matthewmanela.com/category/haskell/feed/" rel="self" type="application/rss+xml" />
	<link>http://matthewmanela.com</link>
	<description>The life and work of Matthew Manela</description>
	<lastBuildDate>Wed, 01 Sep 2010 21:54:57 +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>Prime Factorization using Unfold in Haskell</title>
		<link>http://matthewmanela.com/2009/03/17/prime-factorization-using-unfold-in-haskell/</link>
		<comments>http://matthewmanela.com/2009/03/17/prime-factorization-using-unfold-in-haskell/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 16:53:00 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blogs.msdn.com/matt/archive/2009/03/17/prime-factorization-using-unfold-in-haskell.aspx</guid>
		<description><![CDATA[I randomly yesterday started thinking about the unfoldr function in Haskell while working out at the gym (how nerdy is that, I am lifting iron but thinking of functional programming). Unfoldr take a single and an unfolding function and turns it into a ... <a href="http://matthewmanela.com/2009/03/17/prime-factorization-using-unfold-in-haskell/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I randomly yesterday started thinking about the <strong>unfoldr </strong>function in <a href="http://en.wikipedia.org/wiki/Haskell_(programming_language)">Haskell</a> while working out at the gym (how nerdy is that, I am lifting iron but thinking of functional programming). Unfoldr take a single and an unfolding function and turns it into a list (the opposite of fold).  At the gym I was thinking about an application where I can use this and I decided that when I got home I would use it to write a prime factorization function.  This is a method that when given a number returns the list of its prime factors.<br class="spacer_" /></p>

<p>It was easy to write the only part I am not pleased about is the code I used to deal with tuples.  It seems clumsy and I am still looking for a way to clean that up.<br class="spacer_" /></p>

<p>One note: The code below references a list of prime numbers called primes , which is not shown.<br class="spacer_" /></p>

<p>Here is the code:<br class="spacer_" /></p>

<pre class="brush:haskell">primeFactors x = unfoldr findFactor x
                where
                  first (a,b,c) = a
                  findFactor 1 = Nothing
                  findFactor b = (\(_,d,p)-&gt; Just (p, d))
                                 $ head $ filter ((==0).first)
                                 $  map (\p -&gt; (b `mod` p, b `div` p, p))  primes
</pre>

<p>This function will take any number which is greater than 1 and return a list of its prime factors.  But don’t take my word for it, I wrote a quickcheck property to ensure the prime factors multiply back to the original number:<br class="spacer_" /></p>

<pre class="brush:haskell">
prop_factors num =  num &gt; 1 ==&gt; num == (foldr1 (*) $ primeFactors num)
</pre>

<p>When running quickcheck on this property you see the following:<br class="spacer_" /></p>

<p>quickCheck prop_factors <br />
 OK, passed 100 tests.<br class="spacer_" /></p>

<div id="_mcePaste" style="position: absolute; left: -10000px; top: 240px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(\(_,d,p)-&gt; Just (p, d))</div>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2009/03/17/prime-factorization-using-unfold-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parameterized State Transformer Monad in F#?</title>
		<link>http://matthewmanela.com/2008/11/05/parameterized-state-transformer-monad-in-f-2/</link>
		<comments>http://matthewmanela.com/2008/11/05/parameterized-state-transformer-monad-in-f-2/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 08:30:29 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">/b/matt/archive/2008/11/04/parameterized-state-transformer-monad-in-f.aspx</guid>
		<description><![CDATA[I have have been playing around with F# and I decided to create a state monad.&#160; This worked out really well since I was able to leverage the F# computation expressions.&#160; I then decided to try to extend this and make it more general by creatin... <a href="http://matthewmanela.com/2008/11/05/parameterized-state-transformer-monad-in-f-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><p>I have have been playing around with F# and I decided to create a state monad.&nbsp; This worked out really well since I was able to leverage the <a href="http://blogs.msdn.com/dsyme/archive/2007/09/22/some-details-on-f-computation-expressions-aka-monadic-or-workflow-syntax.aspx" >F# computation expressions</a>.&nbsp; I then decided to try to extend this and make it more general by creating a parameterized state transformer monad.&nbsp; This is a state monad which encapsulates another monad.&nbsp; What this allow you to do is turn any computation into a statefull one.</p> <p>&nbsp;</p> <p>This concept exists in Haskell which you can see <a href="http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-State.html#3" >here</a>. However, my attempts at replicating this in F# failed.&nbsp; Unlike in Haskell, the computation expressions in F# don&#8217;t share a common interface (or type class).&nbsp; This prevents a computation from being able to generically take another computation as a parameter.&nbsp; The reason is that an operation on the parameterized state transformer monad such as bind will result in a bind called on its encapsulated monad.&nbsp; But since there is no interface for computations there is no bind method to call.&nbsp; </p> <p>I attempted to fix this by creating my own monad interface but this didn&#8217;t work:</p> <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"> <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   1:</span> type Monad =</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>     abstract Bind : 'm * ('a -<span style="color: #0000ff">&gt;</span> 'm) -<span style="color: #0000ff">&gt;</span> 'm</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   3:</span>     abstract Delay : (unit -<span style="color: #0000ff">&gt;</span>'m) -<span style="color: #0000ff">&gt;</span> 'm</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     abstract Let : 'a * ('a -<span style="color: #0000ff">&gt;</span> 'm) -<span style="color: #0000ff">&gt;</span> 'm</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   5:</span>     abstract Return : 'a -<span style="color: #0000ff">&gt;</span> 'm</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     abstract Zero : unit -<span style="color: #0000ff">&gt;</span> 'm</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   7:</span>     abstract Combine : 'm -<span style="color: #0000ff">&gt;</span> 'm2 -<span style="color: #0000ff">&gt;</span> 'm3</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     abstract Run : (unit -<span style="color: #0000ff">&gt;</span>'m) -<span style="color: #0000ff">&gt;</span> 'm</pre></div></div></p>

<p>&nbsp;</p>

<p>After playing with that and failing I ended up with a less than ideal solution.&nbsp; Given a Maybe monad like below:</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   1:</span> // Maybe Monad    </pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> type MaybeBuilder() =</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   3:</span>     member b.Return(x) = Some x</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     member b.Run(f) = f()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   5:</span>     member b.Delay(f) = f</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     member b.Let(p,rest) = rest p</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   7:</span>     member b.Zero () = None</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     member b.Combine(m1,dm2) = match m1 with</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   9:</span>                                  | None -<span style="color: #0000ff">&gt;</span> dm2()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>                                  | x -<span style="color: #0000ff">&gt;</span> x</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  11:</span>&nbsp; </pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>     member b.Bind(p,rest) = match p with </pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  13:</span>                             | None -<span style="color: #0000ff">&gt;</span> None</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>                             | Some r -<span style="color: #0000ff">&gt;</span> rest r</pre></div></div>

<p>&nbsp;</p>

<p>I created a state transformer monad which take an argument of type m:MaybeBuilder</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   1:</span> type StateMBuilder(m:MaybeBuilder) = </pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>     member b.Return(x) = fun s -<span style="color: #0000ff">&gt;</span> m.Return (x,s)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   3:</span>     member b.Run(f) = fun inp -<span style="color: #0000ff">&gt;</span> (f inp)()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     member b.Delay(f) = fun inp -<span style="color: #0000ff">&gt;</span> fun () -<span style="color: #0000ff">&gt;</span> f() inp</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   5:</span>     member b.Let(p,rest) = rest p</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     member b.Zero () = fun s -<span style="color: #0000ff">&gt;</span> m.Zero()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   7:</span>     member b.Bind(p,rest) = fun s -<span style="color: #0000ff">&gt;</span> m.Bind(p s,fun (v,s2) -<span style="color: #0000ff">&gt;</span> rest v s2)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     member b.Combine(p1,dp2) = fun s -<span style="color: #0000ff">&gt;</span> m.Combine(p1 s, dp2 s)</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   9:</span>&nbsp; </pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>     // State specific functions</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  11:</span>     member b.Update f = fun s -<span style="color: #0000ff">&gt;</span> try m.Return (s, f s) with e -<span style="color: #0000ff">&gt;</span> m.Zero()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>     member b.Read () = b.Update id</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  13:</span>     member b.Set t = b.Update (fun _ -<span style="color: #0000ff">&gt;</span> t)</pre></div></div>

<p>&nbsp;</p>

<p>Now although this type is technically parameterized ;) it isn&#8217;t really the idea since its not generic, it has to be a MaybeBuilder.&nbsp; To use this with a different monad I would need to change m:MaybeBuild to m:SomeOtherMonad.&nbsp; </p>

<p>I am still going to play with this but this is as far as I have gotten.</p>

<p>After all of that here is how you create a state transformer monad parameterized over the maybe monad:</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   1:</span> let maybe = MaybeBuilder()</pre><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> let state = StateMBuilder(maybe)</pre></div></div>

<p>&nbsp;</p>

<p>If anyone has an idea how I can make this work I would love to hear it.</p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/11/05/parameterized-state-transformer-monad-in-f-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a Regular Expression parser in Haskell: Part 4</title>
		<link>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-4/</link>
		<comments>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-4/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:23:05 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Regular Expression]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=295</guid>
		<description><![CDATA[With the previous two modules in place we are now set up to use a DFA to match against a string.&#160; In my implementation I support either a greedy match or an short match.&#160; In a full featured regular expression &#8230; <a href="http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><P>With the previous two modules in place we are now set up to use a DFA to match against a string.&nbsp; In my implementation I support either a greedy match or an short match.&nbsp; In a full featured regular expression engine this ability to choose greedy or not would be per operator but for simplicity I have it for the overall match.&nbsp; </P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>To do the matching I have a general function which will create a list of all matches.&nbsp; Then the difference between short and greedy matching is which of the candidate solutions does it choose.</P></p>

<p><P>This is the method:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> doMatch func machine st [] = doAccept  machine st []</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> doMatch func machine st string =  func $ map (\f -<SPAN style="COLOR: #0000ff">&gt;</SPAN> doMatch&#8217; st f []) (tails string)</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN>     where</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>       doMatch&#8217; state [] soFar = doAccept machine st soFar</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>       doMatch&#8217; state (s:str) soFar = </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>           case findTransition machine s state of</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN>             Nothing -<SPAN style="COLOR: #0000ff">&gt;</SPAN> doAccept machine state soFar</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   8:</SPAN>             Just (from, to, val) -<SPAN style="COLOR: #0000ff">&gt;</SPAN> case doMatch&#8217; to str (soFar ++ [s]) of</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   9:</SPAN>                                       (False,_) -<SPAN style="COLOR: #0000ff">&gt;</SPAN> case canAccept machine to of</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  10:</SPAN>                                                     True -<SPAN style="COLOR: #0000ff">&gt;</SPAN> (True, soFar ++ [s])</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  11:</SPAN>                                                     False -<SPAN style="COLOR: #0000ff">&gt;</SPAN> doMatch&#8217; to str (soFar ++ [s])</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  12:</SPAN>                                       (True,res) -<SPAN style="COLOR: #0000ff">&gt;</SPAN> (True,res)</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>This creates the list of matches and uses the passed in function to determine how to filter to either the shortest or longest match.</P></p>

<p><P>For short or long matches I pass in one of these two functions:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; Get the shortest match</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> shortest matches = case  filter (\s-<SPAN style="COLOR: #0000ff">&gt;</SPAN>fst s) (sort matches) of</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN>                      [] -<SPAN style="COLOR: #0000ff">&gt;</SPAN> (False,&#8221;")</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>                      ms -<SPAN style="COLOR: #0000ff">&gt;</SPAN> head ms</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN> &#8212; Get the longest match</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN> longest matches = last.sort $ matches</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>I created aliases for the functions to make it more handy:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; HEIGHT: 59px; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> (=~) = greedyMatch</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> (=~?) = shortMatch</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>And then the final result:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> <em>SimpleRegex<SPAN style="COLOR: #0000ff">&gt;</SPAN> &#8220;hiphiphiphorray&#8221; =~? &#8220;hip(hip)</em>&#8220;</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> (True,&#8221;hip&#8221;)</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN> <em>SimpleRegex<SPAN style="COLOR: #0000ff">&gt;</SPAN> &#8220;hiphiphiphorray&#8221; =~ &#8220;hip(hip)</em>&#8220;</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN> (True,&#8221;hiphiphip&#8221;)</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>I attached a zip of all the files for this project.</P></p>

<p><P>Enjoy!</P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a Regular Expression parser in Haskell: Part 3</title>
		<link>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-3/</link>
		<comments>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-3/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:22:47 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Regular Expression]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=293</guid>
		<description><![CDATA[The third module in the simple regular expression parser is called: NFAtoDFA.&#160; Which as you might have guessed, takes the NFA that resulted from the first module and converts it into a DFA.&#160; The structure that the DFA uses is &#8230; <a href="http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><P>The third module in the simple regular expression parser is called: NFAtoDFA.&nbsp; Which as you might have guessed, takes the NFA that resulted from the first module and converts it into a DFA.&nbsp; The structure that the DFA uses is the same that the NFA uses since they are both finite state machines.</P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>Converting an NFA to a DFA requires mapping sets of nodes in the NFA to a single node in the DFA.&nbsp; Many nodes in a NFA will correspond to one node in the DFA.&nbsp; Making this change requires updating transitions to point to and from sets of nodes.&nbsp; To manage this transformation I create a state monad using the following context:</P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><DIV style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: #808080 1px solid; CURSOR: text; BORDER-RIGHT: #808080 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; The state which we pass to build the DFA</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> data ConvertContext = ConvertContext { nfa :: FiniteMachine,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN>                                        trans :: [Transition],</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>                                        setMap :: Map.Map (Set Node) Integer,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>                                        setStack :: [Set Node],</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>                                        begin :: Node,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN>                                        accept :: Set Node,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   8:</SPAN>                                        nextNode :: Node</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   9:</SPAN>                                      } deriving (Show, Eq)</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  10:</SPAN> type ConvertState a = State ConvertContext a</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>Most of the code in this module is just managing this context and updating it according to two operation:</P></p>

<p><OL>
<LI>Epsilon Closure</LI></p>

<p><LI>Set Move</LI>
</OL></p>

<p><P>These are explained in more detail in <A href="http://www.codeproject.com/KB/recipes/OwnRegExpressionsParser.aspx" target=_blank mce_href="http://www.codeproject.com/KB/recipes/OwnRegExpressionsParser.aspx">this article</A>. </P></p>

<p><P>Basically, epsilon closure is the process of taking a set of initial nodes and returning a new set of all nodes you can traverse to purely on epsilon transitions.&nbsp; To help with this I created some smaller methods to build up to an epsilon closure.</P></p>

<p><P>First are a couple methods (findToNodes and closure):</P></p>

<p><DIV style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: #808080 1px solid; CURSOR: text; BORDER-RIGHT: #808080 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> closure trans value nodes oldSet = Set.union (findToNodes trans value nodes) oldSet</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> &#8212; Search the table of transitions to find all nodes you can reach given an initial set of nodes</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN> findToNodes trans value fromNodes = foldr match Set.empty trans</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>     where </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>       match (from, to, val) nodes</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN>           | (from == fromNodes) &amp;&amp; (val == value) = Set.insert to nodes</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   8:</SPAN>           | otherwise = nodes</PRE></DIV></DIV>
<P><STRONG>findToNodes</STRONG> searches a transition table for all nodes which go from any node in <STRONG>fromNodes</STRONG> on <STRONG>value</STRONG>.&nbsp; It will builds up a set with all the <STRONG>to</STRONG>&nbsp; nodes that match.&nbsp; </P></p>

<p><P><STRONG>closure </STRONG>wraps findToNodes to let us easily union together an initial set and the nodes we can reach from that set.</P></p>

<p><P>With this in hand we can write clearly a epsilon closure function:</P></p>

<p><DIV style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: #808080 1px solid; CURSOR: text; BORDER-RIGHT: #808080 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; Given an initial set of nodes, find the set of all nodes you can reach by taking </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> &#8212; transitions on epsilon only</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> epsilonClosure trans nodes = foldUntilRepeat Set.union Set.empty $</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>                              iterate (Set.fold (closure trans epsilon) Set.empty) nodes</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>&nbsp; </PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>This function takes full advantage of the lazy nature of Haskell.&nbsp; It repeats the closure on epsilon over and over and streams its results into our function <STRONG>foldUntilRepeat.&nbsp; </STRONG>This method does what it says, it will fold the values that are streamed in until it sees the same value twice.&nbsp; </P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>The set move is just combination of what you have already seen:</P></p>

<p><DIV style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: #808080 1px solid; CURSOR: text; BORDER-RIGHT: #808080 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; Given a starting set of nodes the set of all nodes that you can reach on a given value</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> &#8212; This includes epislonClosure on the desitination nodes</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> moveClosure trans value nodes = epsilonClosure trans $ </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>                                 Set.fold (closure trans value) Set.empty nodes</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>&nbsp; </PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>With these functions in hand, this module just becomes calling them and updating the context until we have no more nodes in the NFA to process.</P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>In the <A href="http://blogs.msdn.com/matt/archive/2008/06/21/writing-a-regular-expression-parser-in-haskell-part-4.aspx" mce_href="/matt/archive/2008/06/21/writing-a-regular-expression-parser-in-haskell-part-4.aspx">next installment</A> I will discuss using the output of this modules to match a regex against a string.</P></p>

<p><P>Also, once again the code is attached.</P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a Regular Expression parser in Haskell: Part 2</title>
		<link>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-2/</link>
		<comments>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-2/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:22:26 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Regular Expression]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=291</guid>
		<description><![CDATA[The first module in my simple regular expression parse is called RegexToNFA.&#160; This module exposes the types that make up a finite state machine and also the functions to convert a regular expression string into a finite state machine. My &#8230; <a href="http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><P>The first module in my simple regular expression parse is called RegexToNFA.&nbsp; This module exposes the types that make up a finite state machine and also the functions to convert a regular expression string into a finite state machine.</P></p>

<p><P>My structure for a FSM follows closely from the <A href="http://en.wikipedia.org/wiki/State_machine#Mathematical_model" target=_blank mce_href="http://en.wikipedia.org/wiki/State_machine#Mathematical_model">mathematical definition</A>:</P></p>

<p><DIV style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: #808080 1px solid; CURSOR: text; BORDER-RIGHT: #808080 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> data FiniteMachine = FiniteMachine{  table :: [Transition],</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN>                                      alphabet :: Set Char,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN>                                      start :: Node,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>                                      final :: Set Node</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN> &#8212; NFA node</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   8:</SPAN> type Node = Integer</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   9:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  10:</SPAN> &#8212; The value for an edge in a NFA</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  11:</SPAN> type TransitionValue = Maybe Char</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  12:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  13:</SPAN> &#8212; A transition in a NFA is a tuple of</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  14:</SPAN> &#8212; StartNode , DestinationNode, Value to transition on</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  15:</SPAN> type Transition = (Node,Node,TransitionValue)</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  16:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  17:</SPAN> &#8212; The value of the edge in the NFA is a Maybe Char </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  18:</SPAN> &#8212; Where Nothing is the epsilon transition</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  19:</SPAN> &#8212; therefore lets just rename Nothing to epsilon</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>I have the value which you transition on as a Maybe Char (which I alias as TransitionValue).&nbsp; This allowed me to define epsilon as Nothing data constructor.&nbsp; </P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>With this structure defined my goal now is to convert a regular expression pattern such as: (a|b)* into a FiniteMachine.&nbsp; In order to do this there is a lot of state that I need to keep track of which naturally leads to the use of the State monad.&nbsp; To do this I set up a structure for what data I want to be kept track of and then create a state monad using that structure:</P></p>

<p><DIV style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: #808080 1px solid; CURSOR: text; BORDER-RIGHT: #808080 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; The state that gets passed around which we used to build up the NFA</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> data ParseContext = Context </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN>                     {</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>                       nodeList :: [Node],</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>                       transitions :: [Transition],</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>                       operators :: OperatorList,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN>                       nextNode :: Node,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   8:</SPAN>                       values :: Set Char</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   9:</SPAN>                     } deriving (Show, Eq)</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  10:</SPAN>&nbsp; </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  11:</SPAN> &#8212; Alias the State data constructor with a more friendly name</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  12:</SPAN> type RegexParseState a = State ParseContext a</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>This structure is passed between functions to allow them to see the current state of the parsing and create a new state.&nbsp; I define many functions, each which deal with a piece of the puzzle of converting the input string into a FSM.&nbsp; I am not going to address them all but I will point out some which is note worth:</P></p>

<p><P><STRONG>convertToNFA</STRONG> &#8211; This is the top level function, it is exposed externally and lets you convert a regex to a NFA.</P></p>

<p><P><STRONG>processOperator</STRONG> &#8211; This function determines when we should execute an operator given its precedence.&nbsp; We assign each operator a precedence which lets us determine when we should execute an operator.&nbsp; For example in the expression a|b*, we want to execute star before we execute union.&nbsp; </P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>Last but not least are the methods which execute the operators.&nbsp; For example, there is one called <STRONG>doConcat</STRONG>, which performs the concatenation of two values in the regular expression. <STRONG>doConcat</STRONG> isn&#8217;t pretty, since its doing the dirty work of examining the state and create a new state to reflect a partially completed FSM.</P></p>

<p><DIV style="BORDER-BOTTOM: #808080 1px solid; BORDER-LEFT: #808080 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: #808080 1px solid; CURSOR: text; BORDER-RIGHT: #808080 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; Execute the concat operator</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> doConcat :: RegexParseState ()</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> doConcat = do</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>   st <SPAN style="COLOR: #0000ff">&lt;</SPAN>- get</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>   let nodes = nodeList st</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>       newNodes = (nodes !! 0) : (nodes !! 3) : (drop 4  nodes)</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN>       newTransitions = transitions st ++ [(nodes !! 2, nodes !! 1, epsilon)]</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   8:</SPAN>       newOperators = tail $ operators st</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   9:</SPAN>   put $ st { nodeList = newNodes,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  10:</SPAN>              transitions = newTransitions ,</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, monospace; BORDER-TOP-STYLE: none; COLOR: #000000; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  11:</SPAN>              operators = newOperators}</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>With all this in place, lets finally see what this module actually outputs.</P></p>

<p><P>&gt; convertToNFA &#8220;a|(bc)*&#8221;</P></p>

<p><P>FiniteMachine {table = <BR>[(4,5,Just 'c'),(2,3,Just 'b'),(0,1,Just'a'),<BR>(3,4,Nothing),(6,2,Nothing),(6,0,Nothing),<BR>(1,7,Nothing),(5,7,Nothing),(8,6,Nothing),<BR>(8,7,Nothing),(7,9,Nothing),(9,8,Nothing)], <BR>alphabet = fromList &#8220;abc&#8221;, <BR>start = 8, <BR>final = fromList [9]} 
<P>If you examine the table list in the output, you will see all the transitions for the NFA that accepts &#8220;a|(bc)*&#8221; and that the start state is node 8 and the accept state is node 9.&nbsp; </P></p>

<p><P>I uploaded the RegexToNFA.hs file for your examination.&nbsp; I tried to comment it a good amount and I feel it should be pretty easy to read and understand.</P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>In the next part I will talk about the next modules: <A href="http://blogs.msdn.com/matt/archive/2008/06/09/writing-a-regular-expression-parser-in-haskell-part-3.aspx" mce_href="/matt/archive/2008/06/09/writing-a-regular-expression-parser-in-haskell-part-3.aspx">NFAtoDFA</A></P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a Regular Expression parser in Haskell: Part 1</title>
		<link>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-1/</link>
		<comments>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-1/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:22:02 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Regular Expression]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=289</guid>
		<description><![CDATA[A few weeks ago I read this article about writing a simple regular expression parser.&#160; That article does a really good job of explaining the theory behind regular expression.&#160; It then goes step by step into how to write a &#8230; <a href="http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><P>A few weeks ago I read <A href="http://www.codeproject.com/KB/recipes/OwnRegExpressionsParser.aspx" target=_blank mce_href="http://www.codeproject.com/KB/recipes/OwnRegExpressionsParser.aspx">this article</A> about writing a simple regular expression parser.&nbsp; That article does a really good job of explaining the theory behind regular expression.&nbsp; It then goes step by step into how to write a program (he uses C++) to parse a regular expression, convert it into a NFA, convert that into a DFA and then use that DFA to match strings.</P></p>

<p><P>After reading that I decided to write my own simple regular expression parser using Haskell.&nbsp; I saw it as a challenge to try to see how you deal with a more complex program in a pure functional language.&nbsp; After a couple weeks ( Grand Theft Auto 4 kind of ruined my progress for a while ) I have some results.</P></p>

<p><P>I split the project into 3 modules. </P></p>

<p><OL>
<LI><A href="http://blogs.msdn.com/matt/archive/2008/06/02/writing-a-regular-expression-parser-in-haskell-part-2.aspx" target=_blank mce_href="http://blogs.msdn.com/matt/archive/2008/06/02/writing-a-regular-expression-parser-in-haskell-part-2.aspx">RegexToNFA</A> &#8211; Provides functionality to parse a simple regular expression and return a NFA. 
<OL>
<LI>This modules also define the FiniteMachine type which is a general structure for finite state automata.</LI>
</OL></p>

<p><LI>NFAtoDFA &#8211; Providers functionality to convert a NFA into a DFA. 
<OL>
<LI>This module uses the same FiniteMachine type from RegexToNFA</LI>
</OL></p>

<p><LI>SimpleRegex &#8211; Provides the functionality to give take a regular expression and a string and return what it matches (if it matches anything). 
<OL>
<LI>This modules uses RegexToNFA and sends its results to NFAtoDFA and then uses the resulting DFA to match against a string.</LI>
</OL>
</LI>
</OL></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>This is a very simple and limited regular expression parser.&nbsp; It supports only union(|), concatenation, closure(*) and parenthesis.&nbsp; In addition, I don&#8217;t preserve information after the NFA is created about the location of the parenthesis.&nbsp; This means you can&#8217;t pull out sub-matches when a entire expression matches.</P></p>

<p><P>In my next three I will talk about each module and point out interesting parts of them.&nbsp; There is nothing too complex but shows how to approach it in Haskell (making heavy use of the State monad).</P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>If you want to see a much more complex and full featured regular expression parser written in Haskell take a look at <A href="http://www.dcs.gla.ac.uk/~meurig/regexp/" target=_blank mce_href="http://www.dcs.gla.ac.uk/~meurig/regexp/">this</A>.</P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P><A href="http://blogs.msdn.com/matt/archive/2008/06/02/writing-a-regular-expression-parser-in-haskell-part-2.aspx" target=_blank mce_href="http://blogs.msdn.com/matt/archive/2008/06/02/writing-a-regular-expression-parser-in-haskell-part-2.aspx">Click here</A> to continue to Part 2.</P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/writing-a-regular-expression-parser-in-haskell-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Breadth First Tree Traversal in Haskell</title>
		<link>http://matthewmanela.com/2008/03/11/breadth-first-tree-traversal-in-haskell/</link>
		<comments>http://matthewmanela.com/2008/03/11/breadth-first-tree-traversal-in-haskell/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:20:20 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=283</guid>
		<description><![CDATA[As my interest in functional languages has grown, I have become increasingly interested in using them to implement algorithms which I can already write with imperative languages. For example, I was taught to implement (and I assume most other people &#8230; <a href="http://matthewmanela.com/2008/03/11/breadth-first-tree-traversal-in-haskell/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><P>As my interest in functional languages has grown, I have become increasingly interested in using them to implement algorithms which I can already write with imperative languages.</P></p>

<p><P>For example, I was taught to implement (and I assume most other people as well)&nbsp; a breadth first traversal of a tree using a queue and a loop.&nbsp; An example using this method can be found at the <A href="http://en.wikipedia.org/wiki/Breadth-first_search" target=_blank mce_href="http://en.wikipedia.org/wiki/Breadth-first_search">wikipedia page for a breadth first search</A>.&nbsp; When I wanted to try implement a breadth first search in Haskell I quickly realized that algorithm wouldn&#8217;t port over very well.&nbsp; I thought a bit and was able to come up with this algorithm:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; My Implementation</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> breadth :: Tree a -<SPAN style="COLOR: #0000ff">&gt;</SPAN> [a]</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> breadth nd =  map rootLabel $ nd : (breadth&#8217; [nd])</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>     where             </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>       breadth&#8217; [] = []</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>       breadth&#8217; nds = let cs = foldr ((++).subForest) [] nds in</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN>                      cs ++ breadth&#8217; cs</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>The idea was that each call to breadth&#8217; takes a list of nodes (which represents of level of the tree) and will concatenate the children of each of those nodes together and recursively call itself again with that list.&nbsp; This works but its not pretty Haskell.&nbsp; When choosing Haskell (from what I have learned) it is best if you can avoid explicit recursion and use built in combinators.&nbsp; After I coded my breadth first traversal function I decided to look into the Haskell standard libraries to see how it is done there.&nbsp; What I found was a function called levels which returns a list of lists, where each sub-list is a level of the tree.&nbsp; I slightly modified this to have the same functionality as my breadth function which creates one list of all the nodes in the breadth first order.</P></p>

<p><P>This is the resulting code:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> &#8212; Haskell Standard Libraray Implementation</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> br :: Tree a -<SPAN style="COLOR: #0000ff">&gt;</SPAN> [a]</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> br t = map rootLabel $</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>        concat $</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>        takeWhile (not . null) $                </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>        iterate (concatMap subForest) [t]</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>This is really slick implementation of what I did above.&nbsp; The algorithm is the same but the way they went about writing it is so much prettier. </P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/breadth-first-tree-traversal-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Palindrome Creator in Haskell</title>
		<link>http://matthewmanela.com/2008/03/11/palindrome-creator-in-haskell/</link>
		<comments>http://matthewmanela.com/2008/03/11/palindrome-creator-in-haskell/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:15:48 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=269</guid>
		<description><![CDATA[The past few days I have been solving problems at this site called Project Euler.&#160; This site contains many seemingly simple math programming problems.&#160; I have been using Haskell to solve the problems on the site and in order to &#8230; <a href="http://matthewmanela.com/2008/03/11/palindrome-creator-in-haskell/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><P>The past few days I have been solving problems at this site called <A href="http://projecteuler.net/" target=_blank mce_href="http://projecteuler.net/">Project Euler</A>.&nbsp; This site contains many seemingly simple math programming problems.&nbsp; I have been using Haskell to solve the problems on the site and in order to help solve one of the problems I wrote this bit of code to generate <A href="http://en.wikipedia.org/wiki/Palindrome" target=_blank mce_href="http://en.wikipedia.org/wiki/Palindrome">palindromes</A>.&nbsp; </P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> palindrome :: (Integral a) =<SPAN style="COLOR: #0000ff">&gt;</SPAN> a -<SPAN style="COLOR: #0000ff">&gt;</SPAN> [Char] -<SPAN style="COLOR: #0000ff">&gt;</SPAN> [String]</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> palindrome n al =  concat  $  map (pal n) al</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN>     where </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>       pal :: (Integral a)=<SPAN style="COLOR: #0000ff">&gt;</SPAN> a -<SPAN style="COLOR: #0000ff">&gt;</SPAN> Char -<SPAN style="COLOR: #0000ff">&gt;</SPAN> [String]</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>       pal n x </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>           | n <SPAN style="COLOR: #0000ff">&gt;</SPAN> 2 =  map (surround x) (palindrome (n-2) al)</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN>           | n <SPAN style="COLOR: #0000ff">&gt;</SPAN> 1 = [[x,x]]</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   8:</SPAN>           | otherwise = [[x]]</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   9:</SPAN>           where </PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  10:</SPAN>             surround :: Char -<SPAN style="COLOR: #0000ff">&gt;</SPAN> String -<SPAN style="COLOR: #0000ff">&gt;</SPAN> String</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">  11:</SPAN>             surround lt str = [lt] ++ str ++ [lt]</PRE></DIV></DIV>
<P mce_keep="true">&nbsp;</P></p>

<p><P>This code take a length(as an integer) and a list of characters and returns all possible palindromes that can be created.&nbsp; For example:</P></p>

<p><P>palindrome 3 ['a'..'f']</P></p>

<p><P>will result in</P></p>

<p><P>["aaa","aba","aca","ada","aea","afa","bab","bbb","bcb","bdb",</P></p>

<p><P>"beb","bfb","cac","cbc","ccc","cdc","cec","cfc","dad","dbd",</P></p>

<p><P>"dcd","ddd","ded","dfd","eae","ebe","ece","ede","eee",</P></p>

<p><P>"efe","faf","fbf","fcf","fdf","fef","fff"]&nbsp; </P></p>

<p><P mce_keep="true">&nbsp;</P></p>

<p><P>While I doubt this is the greatest implementation of a method which generates palindromes,&nbsp; it was the first one I came up with and I am curious if anyone can do it in a very different (or <EM>better</EM>) way. So, if anyone reading this wants to show me a different way (in any language) feel free.</P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/palindrome-creator-in-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Who would have thunk it?</title>
		<link>http://matthewmanela.com/2008/03/11/who-would-have-thunk-it/</link>
		<comments>http://matthewmanela.com/2008/03/11/who-would-have-thunk-it/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:11:01 +0000</pubDate>
		<dc:creator>Matthew</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=261</guid>
		<description><![CDATA[I recently read this article about Lazy Computation in C#. What the article discusses is creating lazy evaluation in C#. Lazy evaluation is a key feature of functional languages like Haskell but is not common in imperative languages.  It is &#8230; <a href="http://matthewmanela.com/2008/03/11/who-would-have-thunk-it/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently read this article about <a href="http://msdn2.microsoft.com/vcsharp/bb870976.aspx">Lazy Computation in C#</a>. What the article discusses is creating lazy evaluation in C#.</p>

<p>Lazy evaluation is a key feature of functional languages like Haskell but is not common in imperative languages.  It is used in Haskell because it implements parameter passing on a <a href="http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_need" target="_blank">call by need</a> basis.  What this means is that a functions arguments are not executed until they are used but once used the argument retains its calculated value.  This is good because it prevents wasted computation since if a argument isn&#8217;t used it isn&#8217;t executed.</p>

<p>The article goes into details about how to create lazily evaluated arguments and why they are useful.</p>

<p><br class="spacer_" /></p>

<p>Now, I don&#8217;t know if anyone else found this posts title funny but I did because a lazily evaluated argument used in Haskell and that the article shows how to create is commonly referred to as a <a href="http://en.wikipedia.org/wiki/Thunk" target="_blank">Thunk</a>.  :)</p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/who-would-have-thunk-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
