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

Maciej Piechotka uzytkownik2 at gmail.com
Thu Apr 29 17:07:01 EDT 2010


On Thu, 2010-04-29 at 13:29 -0700, 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 
> this simplified example (about 30 more lines of Haskell code, or 
> an equivalent program in C++ (130 lines of code). 

1. Use strong typing. Or any typing

data Card = Value `Of` Color
data Color = Spades | Hearts | Diamonds | Clubs
data Value = A | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 | J | Q | K

type Deck = [Card]

Now saying K `Of` Spades is nicer then 32 or anything. Also It allows to
have it much nicer:

check (A `Of` Clubs) = "You guessed my card!"
check _              = "Try again!"

You won't get invalid card (as 53) - it is guaranteed by the system.

2. User guards instead of nested if's:

test a b c | a == b = "Hello"
           | a == c = "Hi"
           | b == c' = "Howdy"
           | otherwise = "Goodbye"
           where c' = c + 1
vs.

test a b c = if a == b
             then "Hello"
             else if a == c
             then "Hi"
             else if b == c'
             then "Howdy"
             else "Goodbye"
             where c' = c + 1

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).

4. Discard result you don't need:

isDone  (LSt gs strat iA iTh i aA iB iC bDone) = bDone
isDone  (LSt _ _ _ _ _ _ _ _ _ bDone) = bDone

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

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:

map f (x:xs) = f x:map f xs 
-- Good - take something x from list of somethins
map _ []     = []

Regards
PS. Sorry - I haven't had time to look into code very deeply. 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
Url : http://www.haskell.org/pipermail/beginners/attachments/20100429/9a6d5df9/attachment.bin


More information about the Beginners mailing list