<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Monad.liftM</title>
	<atom:link href="http://liftm.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://liftm.wordpress.com</link>
	<description>liftM :: Monad a =&#62; (b -&#62; c) -&#62; a b -&#62; a c</description>
	<lastBuildDate>Tue, 12 Jun 2007 05:29:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='liftm.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Monad.liftM</title>
		<link>http://liftm.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://liftm.wordpress.com/osd.xml" title="Monad.liftM" />
	<atom:link rel='hub' href='http://liftm.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Scientific.Dimension: Type Arithmetic and Physical Units in Haskell</title>
		<link>http://liftm.wordpress.com/2007/06/03/scientificdimension-type-arithmetic-and-physical-units-in-haskell/</link>
		<comments>http://liftm.wordpress.com/2007/06/03/scientificdimension-type-arithmetic-and-physical-units-in-haskell/#comments</comments>
		<pubDate>Mon, 04 Jun 2007 04:08:41 +0000</pubDate>
		<dc:creator>liftm</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://liftm.wordpress.com/2007/06/03/scientificdimension-type-arithmetic-and-physical-units-in-haskell/</guid>
		<description><![CDATA[One of Haskell&#8217;s most outstanding features is it&#8217;s type-checker. Mis-matching types are a quick indication that something is wrong with a particular piece of code. And type annotations are useful documentation tool that provides hints about the uses of a function. Type checking is however not unique to programming languages. There is a similar concept [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=liftm.wordpress.com&amp;blog=1091210&amp;post=7&amp;subd=liftm&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of Haskell&#8217;s most outstanding features is it&#8217;s type-checker. Mis-matching types are a quick indication that something is wrong with a particular piece of code. And type annotations are useful documentation tool that provides hints about the uses of a function. Type checking is however not unique to programming languages. There is a similar concept in Physics: Units. Some programming languages, such as Mathematica provide built-in unit-checking.  The Haskell language lends itself to this purpose very nicely, due to it&#8217;s type-checking system. As opposed to Mathematica, this can be done without changes to the core language itself.</p>
<p>This post will start out by introducing simple type arithmetic using Peano numerals and progresses to implementing a full unit checker on top of the Haskell language. The post is also available as a <a href="http://scientific-dimension.googlecode.com/files/Dimension.lhs">literate Haskell module</a>.</p>
<p>The Glasgow Haskell Compiler (GHC) is used, as we will require the use of the -fglasgow-exts and -fallow-undecidable-instances extensions.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#993333;">{-# OPTIONS <span style="color:#330099;">-</span>fglasgow<span style="color:#330099;">-</span>exts #-}</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#993333;">{-# OPTIONS <span style="color:#330099;">-</span>fallow<span style="color:#330099;">-</span>undecidable<span style="color:#330099;">-</span>instances #-}</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">module</span> Scientific<span style="color:#330099;">.</span>Dimensions <span style="color:#330099;">where</span></pre>
</blockquote>
<h2> Arithmetic in the type-checker</h2>
<p>In our unit-checking code, we will need the ability to add and subtract numbers in the type system. The numbers themselves are represented using Peano numerals. Positive Peano numerals are composed of two parts: Succ and Zero. In Haskell, their definition would look like this:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Peano numerals</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> Zero <span style="color:#330099;">=</span> Zero <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> Succ n <span style="color:#330099;">=</span> Succ n <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span></pre>
</blockquote>
<p>Where Zero represents the number &#8220;0&#8243;, and Succ is the &#8220;successor&#8221; of a number.  For example, the type &#8216;Succ Zero&#8217; is &#8220;1&#8243;, and &#8216;Succ (Succ (Succ Zero))&#8217; is the number &#8220;3&#8243;. To add two numbers, we create a Haskell type class.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">class</span> Add a b c <span style="color:#330099;">|</span> a b <span style="color:#330099;">-&gt;</span> c <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add <span style="color:#330099;">::</span> a <span style="color:#330099;">-&gt;</span> b <span style="color:#330099;">-&gt;</span> c</pre>
</blockquote>
<p>In the above class definition, the type variables &#8216;a&#8217; and &#8216;b&#8217; are the inputs to the calculation, and &#8216;c&#8217; is the resulting output type.  The &#8220;a b -&gt; c&#8221; part tells the type-checker that the type-variable &#8216;c&#8217; can be determined by knowing &#8216;a&#8217; and &#8216;b&#8217;. In other words, a and b &#8220;determine&#8221; c. This means that for every possible case of &#8216;a&#8217; and &#8216;b&#8217;, we will have to specify the resulting &#8216;c&#8217;. Here&#8217;s our first case:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Adding any number to Zero returns that number</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Add num Zero num <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add num Zero <span style="color:#330099;">=</span> num</pre>
</blockquote>
<p>Then, we need to cover the reverse condition: adding Zero to a positive number. We only accept positive numbers here, since the case of adding Zero to Zero is already covered by the previous case.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Adding Zero to a positive number returns that number</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Add Zero <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add Zero <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Succ a</pre>
</blockquote>
<p>Now, we need to cover the slightly more complicated case of adding any two positive numbers. This is done recursively: Given the positive numbers &#8216;Succ a&#8217; and &#8216;Succ b&#8217;, we first calculate &#8216;c = a + b&#8217;, and then return &#8216;c + 2&#8242;. Note that &#8216;a&#8217; is equal to &#8216;Succ a&#8217; minus one, and that &#8216;c + 2&#8242; is the same as &#8216;Succ (Succ c)&#8217;.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Adding two positive numbers <span style="color:#330099;">'</span>Succ a<span style="color:#330099;">'</span> and <span style="color:#330099;">'</span>Succ b<span style="color:#330099;">'</span> returns <span style="color:#330099;">'</span>Succ <span style="color:#330099;">(</span>Succ <span style="color:#330099;">(</span>a <span style="color:#330099;">+</span> b<span style="color:#330099;">))'</span></span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Add a b c <span style="color:#330099;">=&gt;</span> <span style="color:#888888;">-- This means<span style="color:#330099;">:</span> c <span style="color:#330099;">=</span> a <span style="color:#330099;">+</span> b</span>
<span style="color:#aa0099;">&gt;</span>          Add <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ <span style="color:#330099;">(</span>Succ c<span style="color:#330099;">))</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Succ <span style="color:#330099;">(</span>Succ c<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>                 <span style="color:#330099;">where</span> c <span style="color:#330099;">=</span> add a b</pre>
</blockquote>
<p>In the above instance declaration, everything before the &#8216;=&gt;&#8217; symbol is a precondition. Since we calculate &#8216;c = add a b&#8217;, we need to make sure that addition is defined on &#8216;a&#8217; and &#8216;b&#8217; with result-type &#8216;c&#8217;. This is the reason for the pre-condition.</p>
<p>In our unit-checking code, we will also need negative numbers. They are defined using &#8216;Prec&#8217;, where &#8216;Prec&#8217; stands for &#8220;preceding&#8221;. For example, &#8216;Prec (Prec Zero)&#8217; represents the number &#8220;-2&#8243;.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Negative Peano numerals</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> Prec n <span style="color:#330099;">=</span> Prec n</pre>
</blockquote>
<p>Of course, we will have to extend our definition of &#8216;Add&#8217; to include negative numbers. The new instance declarations are very similar to the ones for positive numbers.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- adding Zero to a negative number returns that number</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Add Zero <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add Zero <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Prec a</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Adding negative numbers <span style="color:#330099;">'</span>Prec a<span style="color:#330099;">'</span> and <span style="color:#330099;">'</span>Prec b<span style="color:#330099;">'</span> returns <span style="color:#330099;">'</span>Prec <span style="color:#330099;">(</span>Prec <span style="color:#330099;">(</span>a <span style="color:#330099;">+</span> b<span style="color:#330099;">))'</span> </span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Add a b c <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Add <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec <span style="color:#330099;">(</span>Prec c<span style="color:#330099;">))</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Prec <span style="color:#330099;">(</span>Prec c<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>                 <span style="color:#330099;">where</span> c <span style="color:#330099;">=</span> add a b</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Adding negative number <span style="color:#330099;">'</span>Prec a<span style="color:#330099;">'</span> to positive number <span style="color:#330099;">'</span>Succ b<span style="color:#330099;">'</span> returns <span style="color:#330099;">'</span>a <span style="color:#330099;">+</span> b<span style="color:#330099;">'</span></span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Add a b c <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Add <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> c <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> add a b</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Reverse <span style="color:#330099;">of</span> above</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Add a b c <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Add <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> c <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   add <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> add a b</pre>
</blockquote>
<p>That&#8217;s it! We are now able to add any two numbers. Let&#8217;s try it out:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- 1 <span style="color:#330099;">=</span> 3 <span style="color:#330099;">-</span> 2</span>
<span style="color:#aa0099;">&gt;</span> one <span style="color:#330099;">=</span> add <span style="color:#330099;">(</span>Succ <span style="color:#330099;">(</span>Succ <span style="color:#330099;">(</span>Succ Zero<span style="color:#330099;">)))</span> <span style="color:#330099;">(</span>Prec <span style="color:#330099;">(</span>Prec Zero<span style="color:#330099;">))</span></pre>
</blockquote>
<p>The type of &#8216;one&#8217; is &#8216;Succ Zero&#8217;. This is determined at compile-time using our recursive class-definition for &#8216;Add&#8217;. We will also want to be able to subtract two numbers. The definition of Sub is almost identical to Add:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">class</span> Sub a b c <span style="color:#330099;">|</span> a b <span style="color:#330099;">-&gt;</span> c <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub <span style="color:#330099;">::</span> a <span style="color:#330099;">-&gt;</span> b <span style="color:#330099;">-&gt;</span> c</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Sub a Zero a <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub a Zero <span style="color:#330099;">=</span> a</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Sub Zero <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub Zero <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Prec a</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Sub Zero <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub Zero <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Succ a</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Sub a b c <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Sub <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ <span style="color:#330099;">(</span>Succ c<span style="color:#330099;">))</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Succ <span style="color:#330099;">(</span>Succ c<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>                 <span style="color:#330099;">where</span> c <span style="color:#330099;">=</span> sub a b</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Sub a b c <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Sub <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec <span style="color:#330099;">(</span>Prec c<span style="color:#330099;">))</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> Prec <span style="color:#330099;">(</span>Prec c<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>                 <span style="color:#330099;">where</span> c <span style="color:#330099;">=</span> sub a b</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Sub a b c <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Sub <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> c <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub <span style="color:#330099;">(</span>Prec a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Prec b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> sub a b</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Sub a b c <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Sub <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> c <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   sub <span style="color:#330099;">(</span>Succ a<span style="color:#330099;">)</span> <span style="color:#330099;">(</span>Succ b<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> sub a b</pre>
</blockquote>
<h2> Lists in the Type System</h2>
<p>We will also need to use lists in our type-checker. Lists have a very simple definition:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Linked list</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> Nil <span style="color:#330099;">=</span> Nil <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> x <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> xs <span style="color:#330099;">=</span> x <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> xs <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span></pre>
</blockquote>
<p>Nil is an empty list, and Cons is a pair of types. A list of an Integer, a String, and a Double is defined like this:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> funkyList <span style="color:#330099;">::</span> Int <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>String <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>Double <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil<span style="color:#330099;">))</span>
<span style="color:#aa0099;">&gt;</span> funkyList <span style="color:#330099;">=</span> 256 <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">("</span>hello world<span style="color:#330099;">"</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>3<span style="color:#330099;">.</span>14159 <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil<span style="color:#330099;">))</span></pre>
</blockquote>
<p>Changing the fixity of the Cons type-constructor will allow us to drop the parentheses.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">infixr</span> 6 <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span></pre>
</blockquote>
<p>Using this definition of lists allows many functions to be implemented in a more type-safe manner than using Haskell lists. For example, the Prelude functions &#8216;head&#8217; and &#8216;tail&#8217; will fail when passed an empty list. If head was instead defined using our new definition for lists, the type-checker would ensure at compile-time that no empty lists are passed as arguments.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> safeHead <span style="color:#330099;">::</span> x <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> xs <span style="color:#330099;">-&gt;</span> x
<span style="color:#aa0099;">&gt;</span> safeHead <span style="color:#330099;">(</span>x <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> xs<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> x</pre>
</blockquote>
<p>Running something like &#8216;safeHead Nil&#8217; will result in a type-error. Implementing functions such as &#8216;foldl&#8217;, &#8216;map&#8217; and &#8216;concat&#8217; is left as an exercise to the reader. (If you can&#8217;t figure it out, make sure to ask for help at #haskell on irc.freenode.org)</p>
<h2> Unit Checking</h2>
<p>We are now ready to start start implementing our unit-checker. Units are represented as a list of numbers that count how much of a certain &#8220;primitive&#8221; unit is contained in our unit. For example, suppose we use use the SI units Meter, Kilogram and Second as our primitive units:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- primitive unit count</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> MeterCount <span style="color:#330099;">=</span> MeterCount <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> KilogramCount <span style="color:#330099;">=</span> KilogramCount <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> SecondCount <span style="color:#330099;">=</span> SecondCount <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span></pre>
</blockquote>
<p>The unit Meter would be defined as having a MeterCount of &#8220;1&#8243;, a KilogramCount of &#8220;0&#8243; and a SecondCount of &#8220;0&#8243;:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">type</span> Meter <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Succ Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>       <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>       <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>       <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<p>Recall that &#8216;Succ Zero&#8217; is the Peano numeral representing &#8220;1&#8243;.  Similarly, the unit of &#8216;meter^2 * kilogram / second^3&#8242; would be defined as:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">type</span> FunkyUnit <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Succ <span style="color:#330099;">(</span>Succ Zero<span style="color:#330099;">))</span>
<span style="color:#aa0099;">&gt;</span>           <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Succ Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>           <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Prec <span style="color:#330099;">(</span>Prec Zero<span style="color:#330099;">))</span>
<span style="color:#aa0099;">&gt;</span>           <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<p>Kilograms and Seconds are defined similar to Meters:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">type</span> Kilogram <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>          <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Succ Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>          <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>          <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">type</span> Second <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>        <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>        <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Succ Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>        <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<p>Unitless values occur quite frequently in physics, so we create a type for them as well:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">type</span> Unitless <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>          <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>          <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>          <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<p>To multiply two units, we define the Mult class:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- multiplies to units</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">class</span> Mult a b c <span style="color:#330099;">|</span> a b <span style="color:#330099;">-&gt;</span> c<span style="color:#330099;">,</span> a c <span style="color:#330099;">-&gt;</span> b<span style="color:#330099;">,</span> b c <span style="color:#330099;">-&gt;</span> a <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   mult <span style="color:#330099;">::</span> a <span style="color:#330099;">-&gt;</span> b <span style="color:#330099;">-&gt;</span> c</pre>
</blockquote>
<p>As with the Add class, &#8216;a&#8217; and &#8216;b&#8217; are the two units multiplied together, and &#8216;c&#8217; is the resulting unit. This time, any two units determine the third. As with the &#8216;Add&#8217; class, we need to instantiate the &#8216;Mult&#8217; class with every possible input.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- multiply empty units</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Mult Nil Nil Nil <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   mult Nil Nil <span style="color:#330099;">=</span> Nil</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- multiply units composed <span style="color:#330099;">of</span> non<span style="color:#330099;">-</span>empty lists recursively</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> <span style="color:#330099;">(</span>Add i j k<span style="color:#330099;">,</span> Mult r s t<span style="color:#330099;">)</span> <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Mult <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> i<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> r<span style="color:#330099;">)</span> <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> j<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> s<span style="color:#330099;">)</span> <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> k<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> t<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   mult <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> i<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> r<span style="color:#330099;">)</span> <span style="color:#330099;">((_,</span> j<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> s<span style="color:#330099;">)</span> <span style="color:#330099;">h1<span style="color:#330099;">&gt;</span>
<span style="color:#aa0099;">&gt;</span>     <span style="color:#330099;">(</span>a<span style="color:#330099;">,</span> add i j<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> mult r s
</span></pre>
</blockquote>
<p>Division of units is very similar to multiplication. In stead of adding unit-counts, they are subtracted.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">class</span> Div a b c <span style="color:#330099;">|</span> a b <span style="color:#330099;">-&gt;</span> c<span style="color:#330099;">,</span> a c <span style="color:#330099;">-&gt;</span> b<span style="color:#330099;">,</span> b c <span style="color:#330099;">-&gt;</span> a <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   divide <span style="color:#330099;">::</span> a <span style="color:#330099;">-&gt;</span> b <span style="color:#330099;">-&gt;</span> c</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- divide empty units</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Div Nil Nil Nil <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   divide Nil Nil <span style="color:#330099;">=</span> Nil</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- divide units composed <span style="color:#330099;">of</span> non<span style="color:#330099;">-</span>empty lists recursively</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> <span style="color:#330099;">(</span>Sub i j k<span style="color:#330099;">,</span> Div r s t<span style="color:#330099;">)</span> <span style="color:#330099;">=&gt;</span>
<span style="color:#aa0099;">&gt;</span>          Div <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> i<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> r<span style="color:#330099;">)</span> <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> j<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> s<span style="color:#330099;">)</span> <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> k<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> t<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   divide <span style="color:#330099;">((</span>a<span style="color:#330099;">,</span> i<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> r<span style="color:#330099;">)</span> <span style="color:#330099;">((_,</span> j<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> s<span style="color:#330099;">)</span> <span style="color:#330099;">h1<span style="color:#330099;">&gt;</span>
<span style="color:#aa0099;">&gt;</span>     <span style="color:#330099;">(</span>a<span style="color:#330099;">,</span> sub i j<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> divide r s
</span></pre>
</blockquote>
<p>Now, we create a Dimension type: a value-unit pair.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#888888;">-- Physical dimension with unit</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">data</span> value <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit <span style="color:#330099;">=</span> value <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit <span style="color:#330099;">deriving</span> <span style="color:#330099;">(</span>Eq<span style="color:#330099;">,</span> Show<span style="color:#330099;">)</span></pre>
</blockquote>
<p>We also want `Dimension` to have lower precedence than `Cons` to eliminate unnecessary parentheses:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">infix</span> 4 <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span></pre>
</blockquote>
<p>To make it easy to create physical dimensions, we create constructors for each of our primitive unit types.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> meter <span style="color:#330099;">::</span> Fractional x <span style="color:#330099;">=&gt;</span> x <span style="color:#330099;">-&gt;</span> x <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> Meter
<span style="color:#aa0099;">&gt;</span> meter x <span style="color:#330099;">=</span> x <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Succ Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>	           `Cons` (KilogramCount, Zero)
<span style="color:#aa0099;">&gt;</span>		   `Cons` (SecondCount, Zero)
<span style="color:#aa0099;">&gt;</span>      		   <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> gram <span style="color:#330099;">::</span> Fractional x <span style="color:#330099;">=&gt;</span> x <span style="color:#330099;">-&gt;</span> x <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> Kilogram
<span style="color:#aa0099;">&gt;</span> gram x <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>0<span style="color:#330099;">.</span>001 <span style="color:#330099;">*</span> x<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      	               <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Succ Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      	 	       <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      		       <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> second <span style="color:#330099;">::</span> Fractional x <span style="color:#330099;">=&gt;</span> x <span style="color:#330099;">-&gt;</span> x <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> Second
<span style="color:#aa0099;">&gt;</span> second x <span style="color:#330099;">=</span> x <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      	            <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      	  	    <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Succ Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      		    <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> unitless <span style="color:#330099;">::</span> Fractional x <span style="color:#330099;">=&gt;</span> x <span style="color:#330099;">-&gt;</span> x <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> Unitless
<span style="color:#aa0099;">&gt;</span> unitless x <span style="color:#330099;">=</span> x <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>MeterCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      	              <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>KilogramCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      		      <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>SecondCount<span style="color:#330099;">,</span> Zero<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span>      		      <span style="color:#330099;">`</span>Cons<span style="color:#330099;">`</span> Nil</pre>
</blockquote>
<p>For SI units it makes sense to define unit-prefixes (kilo, cent, milli, etc.):</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> giga f x  <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 1000000000<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> mega f x  <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 1000000<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> kilo f x  <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 1000<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> deca f x  <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 10<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> deci f x  <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 0.1<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> centi f x <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 0<span style="color:#330099;">.</span>01<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> milli f x <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 0<span style="color:#330099;">.</span>001<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> micro f x <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 0<span style="color:#330099;">.</span>000001<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> nano f x  <span style="color:#330099;">=</span> f <span style="color:#330099;">(</span>x <span style="color:#330099;">*</span> 0<span style="color:#330099;">.</span>000000001<span style="color:#330099;">)</span></pre>
</blockquote>
<p>Using the primitive dimension constructors and prefixes, dimensions are defined like thus:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> mile <span style="color:#330099;">=</span> meter 1609<span style="color:#330099;">.</span>3
<span style="color:#aa0099;">&gt;</span> gravity <span style="color:#330099;">=</span> kilo gram 9<span style="color:#330099;">.</span>8 <span style="color:#330099;">.*</span> meter 1 <span style="color:#330099;">./</span> <span style="color:#330099;">(</span>second 1 <span style="color:#330099;">.*</span> second 1<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> speedOfLight <span style="color:#330099;">=</span> unitless <span style="color:#330099;">(</span>10<span style="color:#330099;">^</span>8<span style="color:#330099;">)</span> <span style="color:#330099;">.*</span> meter 3 <span style="color:#330099;">./</span> second 1</pre>
</blockquote>
<p>It would be nice, if we could instantiate the Prelude Num class to define functions such as (+), (-) and (*) for our dimensions. However, multiplication in the Num class is only allowed on values of equal type. Thus, we need to define our own addition, subtraction, multiplication and division functions:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">.*</span> <span style="color:#330099;">(</span>c <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> d<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">*</span> c<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>mult b d<span style="color:#330099;">)</span></pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">./</span> <span style="color:#330099;">(</span>c <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> d<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">/</span> c<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">(</span>divide b d<span style="color:#330099;">)</span></pre>
</blockquote>
<p>For addition and subtraction, we need to additionally make sure that the units of the two arguments are the same:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">(.+)</span> <span style="color:#330099;">::</span> Num a <span style="color:#330099;">=&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">-&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">-&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">.+</span> <span style="color:#330099;">(</span>c <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">_)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">+</span> c<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b</pre>
</blockquote>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">(.-)</span> <span style="color:#330099;">::</span> Num a <span style="color:#330099;">=&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">-&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">-&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">.-</span> <span style="color:#330099;">(</span>c <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">_)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">-</span> c<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> b</pre>
</blockquote>
<p>However, it does make sense for Unitless dimensions to instantiate Num. That&#8217;s exactly what unitless dimensions are: numbers without unit.</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Num a <span style="color:#330099;">=&gt;</span> Num <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> Unitless<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit<span style="color:#330099;">)</span> <span style="color:#330099;">+</span> <span style="color:#330099;">(</span>b <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">_)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">+</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>   <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit<span style="color:#330099;">)</span> <span style="color:#330099;">-</span> <span style="color:#330099;">(</span>b <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">_)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">-</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>   <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit<span style="color:#330099;">)</span> <span style="color:#330099;">*</span> <span style="color:#330099;">(</span>b <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">_)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">*</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>   abs <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> abs a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>   signum <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit<span style="color:#330099;">)</span> <span style="color:#330099;">=</span> signum a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>   fromInteger i <span style="color:#330099;">=</span> fromInteger i <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>     <span style="color:#330099;">where</span> <span style="color:#330099;">_</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit <span style="color:#330099;">=</span> unitless 1</pre>
</blockquote>
<p>To use the (/) function on Unitless values, we need to instantiate the &#8216;Fractional&#8217; class:</p>
<blockquote>
<pre>
<span style="color:#aa0099;">&gt;</span> <span style="color:#330099;">instance</span> Fractional a <span style="color:#330099;">=&gt;</span> Fractional <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> Unitless<span style="color:#330099;">)</span> <span style="color:#330099;">where</span>
<span style="color:#aa0099;">&gt;</span>   <span style="color:#330099;">(</span>a <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit<span style="color:#330099;">)</span> <span style="color:#330099;">/</span> <span style="color:#330099;">(</span>b <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> <span style="color:#330099;">_)</span> <span style="color:#330099;">=</span> <span style="color:#330099;">(</span>a <span style="color:#330099;">/</span> b<span style="color:#330099;">)</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>   fromRational r <span style="color:#330099;">=</span> fromRational r <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit
<span style="color:#aa0099;">&gt;</span>     <span style="color:#330099;">where</span> <span style="color:#330099;">_</span> <span style="color:#330099;">`</span>Dimension<span style="color:#330099;">`</span> unit <span style="color:#330099;">=</span> unitless 1</pre>
</blockquote>
<h2> Conclusion</h2>
<p>Unit checking is very useful for Scientific applications, and is now possible in the Haskell language. Hopefully, this will encourage Haskell&#8217;s use in the Scientific community.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/liftm.wordpress.com/7/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/liftm.wordpress.com/7/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/liftm.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/liftm.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/liftm.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/liftm.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/liftm.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/liftm.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/liftm.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/liftm.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/liftm.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/liftm.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/liftm.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/liftm.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/liftm.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/liftm.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=liftm.wordpress.com&amp;blog=1091210&amp;post=7&amp;subd=liftm&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://liftm.wordpress.com/2007/06/03/scientificdimension-type-arithmetic-and-physical-units-in-haskell/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/00f7d67bb3a81390e353bb1d3c3f8178?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">liftM</media:title>
		</media:content>
	</item>
	</channel>
</rss>
