More Haskell

posted in Journal
Published April 14, 2007
Advertisement
Ive recently had to complete a paper so I have not been able to do too much programming. However, even in the few days that I have used it Haskell has allowed me to write extremely short yet expressive programs, whose equivalence I would not know how to write so simply in C++ or C#. The programs are pretty simple. In one, I have a function which takes a list of numbers and a function and builds a modulo table using the function which I have defined prior.

Basically it makes a modulo table for Zn= [0.. (n-1)].

aMod :: Int -> Int -> Int -> IntaMod a b m = (a + b) `mod` mmMod a b m = (a * b) `mod` mmodulo_table a f = 	let k = length a in 		[((f i 1 k), (f 1 j k), (f (f i 1 k) (f 1 j k) k) )  | i <- a, j <- a] 

I know the above is not efficient since it applies f at least twice more than it needs to. If anyone knows how it can be improved please tell. However it was done as such to make it easier to check from the Hugs output thing. In a real program I'd simply make a list [f i j k | i <- a, j <- a ] and format it accordingly. But I havent gotten to monads yet :)

modulo_table2 [0..3] aMod[0,1,2,3,1,2,3,0,2,3,0,1,3,0,1,2]modulo_table [0..11] mMod [(0,0,0),(0,1,0),(0,2,0),(0,3,0),(0,4,0),(0,5,0),(0,6,0),(0,7,0),(0,8,0),(0,9,0),(0,10,0),(0,11,0),(1,0,0),(1,1,1),(1,2,2),(1,3,3),(1,4,4),(1,5,5),(1,6,6),(1,7,7),(1,8,8),(1,9,9),(1,10,10),(1,11,11),(2,0,0),(2,1,2),(2,2,4),(2,3,6),(2,4,8),(2,5,10),(2,6,0),(2,7,2),(2,8,4),(2,9,6),(2,10,8),(2,11,10),(3,0,0),(3,1,3),(3,2,6),(3,3,9),(3,4,0),(3,5,3),(3,6,6),(3,7,9),(3,8,0),(3,9,3),(3,10,6),(3,11,9),(4,0,0),(4,1,4),(4,2,8),(4,3,0),(4,4,4),(4,5,8),(4,6,0),(4,7,4),(4,8,8),(4,9,0),(4,10,4),(4,11,8),(5,0,0),(5,1,5),(5,2,10),(5,3,3),(5,4,8),(5,5,1),(5,6,6),(5,7,11),(5,8,4),(5,9,9),(5,10,2),(5,11,7),(6,0,0),(6,1,6),(6,2,0),(6,3,6),(6,4,0),(6,5,6),(6,6,0),(6,7,6),(6,8,0),(6,9,6),(6,10,0),(6,11,6),(7,0,0),(7,1,7),(7,2,2),(7,3,9),(7,4,4),(7,5,11),(7,6,6),(7,7,1),(7,8,8),(7,9,3),(7,10,10),(7,11,5),(8,0,0),(8,1,8),(8,2,4),(8,3,0),(8,4,8),(8,5,4),(8,6,0),(8,7,8),(8,8,4),(8,9,0),(8,10,8),(8,11,4),(9,0,0),(9,1,9),(9,2,6),(9,3,3),(9,4,0),(9,5,9),(9,6,6),(9,7,3),(9,8,0),(9,9,9),(9,10,6),(9,11,3),(10,0,0),(10,1,10),(10,2,8),(10,3,6),(10,4,4),(10,5,2),(10,6,0),(10,7,10),(10,8,8),(10,9,6),(10,10,4),(10,11,2),(11,0,0),(11,1,11),(11,2,10),(11,3,9),(11,4,8),(11,5,7),(11,6,6),(11,7,5),(11,8,4),(11,9,3),(11,10,2),(11,11,1)]


-------------------

The next program I wrote is one which allows one to compose permutation groups and can build cayley tables for said permutation groups. I do not see it being difficult to extend to be more general but then Cayley's Theorem would have that doing that may not even be necessary. hehe. Basically it takes a map described as a tuple (which is basically what a function is in the mathematical sense) and follows the the pairs to create a composition.

{-The task of the algorithim is to go through each tuple in the list and for each tuple try to match the given variable. The matched tuples opposite pair is returned and matched to some iteration -}sec list2 a = head <br><br>o :: [(<span class="cpp-keyword">Int</span>,<span class="cpp-keyword">Int</span>)] -> [(<span class="cpp-keyword">Int</span>,<span class="cpp-keyword">Int</span>)]-> [(<span class="cpp-keyword">Int</span>,<span class="cpp-keyword">Int</span>)]<br>o list1 list2 = let n = length list1 in [ (a, (sec list1 (sec list2 a)) ) | a <- [<span class="cpp-number">1</span>..n]]<br><br><span class="cpp-comment">//////////////</span><br><br>Hugs> a<br>[(<span class="cpp-number">1</span>,<span class="cpp-number">2</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">3</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">1</span>)]<br>Hugs> a `o` e `o` r `o` b<br>(<span class="cpp-number">1</span>,<span class="cpp-number">3</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">2</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">1</span>)]<br><br></pre></div><!–ENDSCRIPT–><br><br>This example works on the symmetry group of a triangle.<pre><br>e,a,b,r,s,t::[(Int,Int)]<br><br>l = [(e,'e'),<br>	(a,'a'),<br>	(b,'b'),<br>	(r,'r'),<br>	(s,'s'),<br>	(t,'t')]<br>	<br>e = [(1,1),(2,2),(3,3)]<br>a = [(1,2),(2,3),(3,1)] <br>b = [(1,3),(2,1),(3,2)]<br><br>r = [(1,1),(2,3),(3,2)]<br>s = [(1,3),(2,2),(3,1)]<br>t = [(1,2),(2,1),(3,3)]<br><br>(&) j k  = <br><br>cayley_table = [  ( b, d, a&c    )  | (a,b) <- l, (c,d) <- l]<br><br>cayley_table<br>[('e','e',"e"),('e','a',"a"),('e','b',"b"),('e','r',"r"),('e','s',"s"),('e','t',"t"),<br>('a','e',"a"),('a','a',"b"),('a','b',"e"),('a','r',"t"),('a','s',"r"),('a','t',"s"),<br>('b','e',"b"),('b','a',"e"),('b','b',"a"),('b','r',"s"),('b','s',"t"),('b','t',"r"),<br>('r','e',"r"),('r','a',"s"),('r','b',"t"),('r','r',"e"),('r','s',"a"),('r','t',"b"),<br>('s','e',"s"),('s','a',"t"),('s','b',"r"),('s','r',"b"),('s','s',"e"),('s','t',"a"),<br>('t','e',"t"),('t','a',"r"),('t','b',"s"),('t','r',"a"),('t','s',"b"),('t','t',"e")]</pre><br>The cayley table is based around assigning pairing a letter to a group element. Then the operator (&) basically matches the element of a predefined list to the composition of the given elements.<br><br><br><!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre><br>#pragma indent<br><span class="cpp-keyword">using</span> System;<br><span class="cpp-keyword">using</span> System.Console;<br><span class="cpp-keyword">using</span> Nemerle.Utility;<br><span class="cpp-keyword">using</span> Nemerle.Collections;<br><br>module Program<br>        <br>    aMod (a :<span class="cpp-keyword">int</span>, b : <span class="cpp-keyword">int</span>, m : <span class="cpp-keyword">int</span>) : <span class="cpp-keyword">int</span><br>        (a + b) % m<br><br>    mMod (a:<span class="cpp-keyword">int</span>, b:<span class="cpp-keyword">int</span>, m : <span class="cpp-keyword">int</span>) : <span class="cpp-keyword">int</span> <br>        (a * b) % m <br>    <br>    modulo_table2 (a : list[<span class="cpp-keyword">int</span>], f : (<span class="cpp-keyword">int</span> * <span class="cpp-keyword">int</span>* <span class="cpp-keyword">int</span>)-> <span class="cpp-keyword">int</span>)  : list[<span class="cpp-keyword">int</span>]<br>        def k = List.Length(a)<br>        $[f(i, j , k)  | i in a, j in a]<br>    <br>    <span class="cpp-comment">//this feels me with unhappiness. if anyone knows how pattern matching on tuples works in nemerle please let me know.  </span><br>    sec(list2 : list[(<span class="cpp-keyword">int</span> * <span class="cpp-keyword">int</span>)], a : <span class="cpp-keyword">int</span>): <span class="cpp-keyword">int</span><br>        def tup = List.Head(List.Filter(list2, fun(x) { <span class="cpp-keyword">if</span>(x[<span class="cpp-number">0</span>]==a)<span class="cpp-keyword">true</span> <span class="cpp-keyword">else</span> <span class="cpp-keyword">false</span>}  ) )<span class="cpp-comment">//  Head $[v[1] | v in list2, v[0] == a]</span><br>        tup[<span class="cpp-number">1</span>]<br><br>    <span class="cpp-keyword">public</span> <span class="cpp-keyword">static</span> @<.> (list1 : list[(<span class="cpp-keyword">int</span> * <span class="cpp-keyword">int</span>)], list2 : list[(<span class="cpp-keyword">int</span> * <span class="cpp-keyword">int</span>)]) : list[(<span class="cpp-keyword">int</span> * <span class="cpp-keyword">int</span>)]<br>        def n = List.Length(list1); <br>        $[ ( <span class="cpp-comment">/**/</span> a, sec(list1, sec(list2, a) ) <span class="cpp-comment">/**/</span>) | a in [<span class="cpp-number">1</span>..n]]<br> <br>    Main() : <span class="cpp-keyword">void</span>  <br>        def m = Int32.Parse(ReadLine()) - <span class="cpp-number">1</span>                  <br>        def z = modulo_table2($[<span class="cpp-number">0</span>..m], aMod)<br>        <br>        def e = [(<span class="cpp-number">1</span>,<span class="cpp-number">1</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">2</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">3</span>)]<br>        def a = [(<span class="cpp-number">1</span>,<span class="cpp-number">2</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">3</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">1</span>)] <br>        def b = [(<span class="cpp-number">1</span>,<span class="cpp-number">3</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">1</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">2</span>)]<br><br>        def r = [(<span class="cpp-number">1</span>,<span class="cpp-number">1</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">3</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">2</span>)]<br>        def s = [(<span class="cpp-number">1</span>,<span class="cpp-number">3</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">2</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">1</span>)]<br>        def t = [(<span class="cpp-number">1</span>,<span class="cpp-number">2</span>),(<span class="cpp-number">2</span>,<span class="cpp-number">1</span>),(<span class="cpp-number">3</span>,<span class="cpp-number">3</span>)]<br>        <br>        <br>        def l = [(e,'e'),(a,'a'),(b,'b'),(r,'r'),(s,'s'),(t,'t')]<br><br>        <span class="cpp-keyword">mutable</span> n = <span class="cpp-number">0</span>;<br>        def chk (j , k)<br>            $[ x[<span class="cpp-number">1</span>] | x in l, x[<span class="cpp-number">0</span>] == j <.> k]     <br>                <br>        def cayley_table = $[  ( b, d, chk(a,c)   )  | (a,b) in l, (c,d) in l]   <br><br>        <span class="cpp-keyword">mutable</span> n = <span class="cpp-number">0</span>;<br>        <br>        foreach(a in z)<br>            Write($<span class="cpp-literal">"$a "</span>)<br>            <span class="cpp-keyword">if</span>(n < m) n++ <br>            <span class="cpp-keyword">else</span> <br>                n=<span class="cpp-number">0</span><br>                WriteLine(<span class="cpp-literal">""</span>)<br>                <br>        ReadLine()<br><br><br><br><br></pre></div><!–ENDSCRIPT–><br><pre><br>12<br>0 1 2 3 4 5 6 7 8 9 10 11<br>1 2 3 4 5 6 7 8 9 10 11 0<br>2 3 4 5 6 7 8 9 10 11 0 1<br>3 4 5 6 7 8 9 10 11 0 1 2<br>4 5 6 7 8 9 10 11 0 1 2 3<br>5 6 7 8 9 10 11 0 1 2 3 4<br>6 7 8 9 10 11 0 1 2 3 4 5<br>7 8 9 10 11 0 1 2 3 4 5 6<br>8 9 10 11 0 1 2 3 4 5 6 7<br>9 10 11 0 1 2 3 4 5 6 7 8<br>10 11 0 1 2 3 4 5 6 7 8 9<br>11 0 1 2 3 4 5 6 7 8 9 10</pre><div>


</div>
Previous Entry Haskell
Next Entry Strict or Lazy
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement