[Haskell-beginners] Re: Converting an imperative program to haskell

Hein Hundal hundalhh at yahoo.com
Thu Apr 29 17:49:16 EDT 2010


--- On Thu, 4/29/10, Maciej Piechotka <uzytkownik2 at gmail.com> wrote:
> Hein Hundal wrote:
> >
> >    I figured I should try a larger program
> in Haskell, so I am
> > converting one of my Mathematica programs, a simulator
> for the
> > card game Dominion, over to Haskell.  Most of
> that is going well
> > except for one patch of imperative code.  My
> Haskell version of
> > this code is ugly.  I was hoping someone could
> recommend a better
> > way to do it.  I will paste a simplified version
> of the code
> > below.  If necessary, I can provide all the other
> code used for
>
> 1. Use strong typing. Or any typing

I simplified the code for the post.  In the real version, I use strong typing.  The Card type is enumerated.  I have been using [Card] instead of calling it a Deck.  I could change that.

> 2. User guards instead of nested if's:

In the "procloop" function, I have if's nested quite deeply.  I could easily use guards.  I will try that.

> 3. Don't use too much variables. 6-8 is probably the
> maximum you should
> deal with (human short-term memory holds about 5-10 points
> of entry.
> Split functions into smaller functions (even in where).

I do have to get the information into the functions, so the only way I can avoid having lots of variables is by introducing new structures.  I can do that.

> 4. Discard result you don't need:
>
> isDone  (LSt gs strat iA iTh i aA iB iC bDone) =
> bDone
> isDone  (LSt _ _ _ _ _ _ _ _ _ bDone) = bDone

Yes, that's much better. 

proc gs' strat = let
      iA     = 1
      iTh    = 0
      i      = 0
      aA     = replicate 20 0
      iB     = 1
      iC     = 0
      bDone  = False
      gs     = apps ("<<<"++show(gs')++">>>") gs'
      lst    = LSt gs strat iA iTh i aA iB iC bDone
      lst2   = until isDone procloop lst 
      isDone  (LSt _  _ _ _ _ _ _  _ bDone) = bDone
      output  (LSt gs _ _ _ _ aA iB iC _) = (iB, iC, appd aA gs)
  in output lst2


> 5. Don't reuse the same name in the same scope (like iA as
> 1 and iA as parameter to isDone).

I did hesitate to use the same parameter name twice. 

> 6. While Haskell have long tradition of having short
> namesit is not
> always good (see 3). Use them only if you are sure it is
> clear what they
> mean:

In the original version, I had longer variable names where they seemed necessary. 


The main sources of ugliness are the long lists of variables.  Every time I call doAct or construct a LoopState variable, I am repeating all those variables.  I will try changing the type of doAct to

doAct :: LoopState -> LoopState

Cheers,
Hein







      


More information about the Beginners mailing list