1

I am very new in haskell-programming. I try to program a simple dice-game, but I don't know to do it in haskell.

 suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool

 suc  (a₁,a₂,a₃) c (d₁,d₂,d₃)

I want to consider each difference dᵢ - aᵢ (but not if aᵢ > dᵢ) and return False if (d1-a1)+(d2-a2)+(d3-a3) are larger than c. (if aᵢ > dᵢ then I sum up 0 instead the difference)

I try something like this:

suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool
suc (a1, a2, a3) c (d1, d2, d3) = ?????
    where diff1 = if (d1 > a1) then d1-a1       
          diff2 = if (d2 > a2) then d2-a2
          diff3 = if (d3 > a3) then d3-a3

2 Answers 2

2
  1. Because in Haskell, else is not a optional part of an if expression, so you need to define diff1 as diff1 = if d1 > a1 then d1 - a1 else 0. Other two are similar.

  2. Notes that > returns a Bool value, so you could just sum these three differences up and compare it with c, and use it as your condition.


There are several ways to define this function:

suc1 (a1, a2, a3) c (d1, d2, d3) = diff1 + diff2 + diff3 <= c
    where diff1 = if d1 > a1 then d1 - a1 else 0
          diff2 = if d2 > a2 then d2 - a2 else 0
          diff3 = if d3 > a3 then d3 - a3 else 0

suc2 (a1, a2, a3) c (d1, d2, d3) = sum diffs <= c
    where diff1 = max (d1-a1) 0
          diff2 = max (d2-a2) 0
          diff3 = max (d3-a3) 0
          diffs = [diff1, diff2, diff3]

suc3 (a1, a2, a3) c (d1, d2, d3) = sum (zipWith diff as ds) <= c
    where diff a d = max (d-a) 0
          as = [a1, a2, a3]
          ds = [d1, d2, d3]
Sign up to request clarification or add additional context in comments.

1 Comment

Nice! Of course, the third alternative would be much shorter if the arguments were already given as lists, as they maybe should.
1

How about this?

suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool
suc (a1, a2, a3) c (d1, d2, d3) = 
    ((if a1> d1 then 0 else d1-a1) + (if a2> d2 then 0 else d2-a2) + (if a3>d3 then 0 else d3-a3) > c )

Or alternatively

suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool
suc (a1, a2, a3) c (d1, d2, d3) = 
    max 0 (d1-a1) + max 0 (d2-a2) + max 0 (d3-a3) > c 

4 Comments

instead of the if's you could try max 0 (d-a)
Great it works, I've only changed >c to <= c, now it's exactly what I want. Thanks a lot
It is possible to pull apart further: suc (a1, a2, a3) c (d1, d2, d3) = (> c) . sum . map (max 0) $ zipWith (-) [d1, d2, d3] [a1, a2, a3]
@JonPurdy You're definitely right it would work, and it would be a correct way to do for bigger data sets, but personally in this case I would prefer the way used in the answer, as the code is much more readable and not much longer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.