How does the template match different ways depending on the specific input?
I have a function:
closeTo61 :: Tactic
closeTo61 s P2 h d e b
| cs + ps < 53 = 0
| cs + ps == 61 = 100 -- Best case
| numWaysToScoreN (61 - (cs + ps)) h b == 0 = 0 -- Worst case
| numWaysToScoreN (61 - (cs + ps)) h b == 1 = 50 -- Strong case
| numWaysToScoreN (61 - (cs + ps)) h b == 2 = 70 -- Very Strong case
| numWaysToScoreN (61 - (cs + ps)) h b >= 3 = 90 -- Extremely Strong case
where
ps = scoreDom d e b
(_,cs) = s
closeTo61 s P1 h d e b
| cs + ps < 53 = 0
| cs + ps == 61 = 100
| numWaysToScoreN (61 - (cs + ps)) h b == 0 = 0
| numWaysToScoreN (61 - (cs + ps)) h b == 1 = 50
| numWaysToScoreN (61 - (cs + ps)) h b == 2 = 70
| numWaysToScoreN (61 - (cs + ps)) h b >= 3 = 90
where
ps = scoreDom d e b
(cs,_) = s
The only reason I did this with two bindings for every possible input of the second argument is because the block where
cs
matches the pattern differently depending on that input.
Is there a way to do this using just one binding and checking the second input inside the block where
to use the correct template?
source to share
You can move the pattern match into a block where
where you define cs
:
closeTo61 s p h d e b
...
where cs = case p of P1 -> fst s; P2 -> snd s
If you do this a lot (and since you defined a type for P1
and P2
, you could be), I would extract this logic into a more meaningful helper function:
component P1 (x, _) = x
component P2 (_, x) = x
Then you can do
closeTo61 s p h d e b
...
where cs = component p s
source to share
Instead, you can do
closeTo61 s p h d e b
| cs + ps < 53 = 0
| ...
where
cs = chooseByP p s
chooseByP P1 = fst
chooseByP P2 = snd
Although, since you only use s
and p
to determine which element to s
use, why use them as separate arguments here?
closeTo61 cs h d e b
| ...
where
ps = scoreDom d e b
closeTo61' s p = closeTo61 (chooseByP p s)
source to share