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

```Hi,

I am new to Haskell.  I programmed in imperative languages
for many years and I have been using Mathematica for the last
15 years which mixes functional and imperative programming.
the first 13.5 chapters of Real World Haskell and doing about 50
of the Euler Problems.  "The Evolution of a Haskell Programmer",

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
an equivalent program in C++ (130 lines of code).

Cheers,
Hein

data LoopState = LSt GameState Strat Int Int Int [Int] Int Int Bool

proc :: GameState -> Strat -> (Int, Int, GameState)
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 gs strat iA iTh i aA iB iC bDone) = bDone
output  (LSt gs strat iA iTh i aA iB iC bDone) = (iB, iC, appd aA gs)
in output lst2

procloop :: LoopState -> LoopState
procloop (LSt gs' strat iA iTh i aA iB iC bDone) = do
let iCd = stratchoose strat gs' iA iTh iB aA
let gs = apps ("iB "++show iB++ "\n" ) gs'
if iA<=0 || i>=20 || actcd gs <=0 || iCd == -1
then LSt gs strat iA iTh (i+1) aA iB iC True
else if iCd == 1
then LSt gs strat iA (iTh+1) (i+1) aA iB iC False
else let
gs2 = delh iCd gs
aA2 = append aA iCd
(iA3, iC3, iB3, gs3, aA3) = doAct iA  iC  iB  gs2 aA2 strat iCd
(iA4, iC4, iB4, gs4, aA4) = doAct iA3 iC3 iB3 gs3 aA3 strat iCd
in if iTh>0
then LSt gs4 strat iA4 (iTh-1) (i+1) aA4 iB4 iC4 False
else LSt gs3 strat iA3 (iTh-1) (i+1) aA3 iB3 iC3 False

```