简体   繁体   中英

Haskell Evaluation

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM