Reputation: 21
I have the following block of code:
data G = F G G | H Int deriving (Show, Eq)
example :: Int -> G -> G
example 0 (H i) = (H i)
example n (H i) = F (example (n-1) (H i)) (example (n-1) (H i))
example n (F i1 i2) = F (example n i1) (example n i2)
When I run example 0 (F (H 1) (H 2))
, as expected it returns F (H 1) (H 2)
When I run example 1 (F (H 1) (H 2))
, it returns F (F (H 1) (H 1)) (F (H 2) (H 2))
This is not what I want. I need to return F (F (H 1) (H 1)) (H 2)
What I mean is on the 6th line, example n (F i1 i2) = F (example n i1) (example n i2)
, I call the recursive function twice. However I wish for (example n i1)
to evaluate first and update the variable n
before we evaluate (example n i2)
Any help/solutions to this exact problem will be greatly appreciated. I have been trying for hours with zero success.
Upvotes: 1
Views: 98
Reputation: 233487
The problem seems to be that you want to use example
to 'update' n
. You can't directly do that, however, since example
returns a G
value, and n
is an Int
.
It seems, then, that you need a function G -> Int
. The issue is that there's no unambiguously correct way to write that function. In fact, there's infinitely many possible implementations. Here's a sample:
evalZero :: G -> Int
evalZero = const 0
evalOne :: G -> Int
evalOne = const 1
evalLeft :: G -> Int
evalLeft (H i) = i
evalLeft (F g _) = evalLeft g
evalRight :: G -> Int
evalRight (H i) = i
evalRight (F _ g) = evalRight g
evalSum :: G -> Int
evalSum (H i) = i
evalSum (F g1 g2) = evalSum g1 + evalSum g2
evalProduct :: G -> Int
evalProduct (H i) = i
evalProduct (F g1 g2) = evalProduct g1 * evalProduct g2
evalPlusOneProduct :: G -> Int
evalPlusOneProduct (H i) = i + 1
evalPlusOneProduct (F g1 g2) = evalPlusOneProduct g1 * evalPlusOneProduct g2
-- etc.
As evalPlusOneProduct
illustrates, you can arbitrarily add or subtract a constant Int
, or, for that matter, multiply by a constant, or perform more complex arbitrary calculations. Since there's infinitely many integers, there's infinitely many implementations (although, granted, technically, we're constrained by the range of Int
).
Once you've figured out how to transform G
into Int
, you can use that function to calculate a new value n1
from n
and the left G
value.
Upvotes: 1