Is there a way to remove duplicate statements in Haskell?

I have the following code in Haskell:

move :: Camera -> (Double, Double, Double) -> Camera
move camera (xt, yt, zt) = camera { cPosition = (x + xt, y + yt, z + zt) }
    where (x, y, z) = cPosition camera

moveForward :: Camera -> Camera
moveForward camera = move camera (-1 * sin ya, 0, -1 * cos ya)
    where (_, ya, _) = cRotation camera

moveBackward :: Camera -> Camera
moveBackward camera = move camera (sin ya, 0, cos ya)
    where (_, ya, _) = cRotation camera

You will notice that functions moveForwardand moveBackwardhave the same operators where. Is there any way to remove this duplication? I have many functions with the same sentences where(read: more than two).

I would prefer not to pass it as another argument - since it will never change. He will always be cRotation.

+3
source share
2 answers

How do I get these functions to take a tuple as an argument and then wrap them with another function that automatically does the boring job of retrieving a tuple?

rotated :: ((Double, Double, Double) -> Camera -> a) -> Camera -> a
rotated f camera = f (cPosition camera) camera

moveForward :: Camera -> Camera
moveForward = rotated moveForward'
    where moveForward' (_, ya, _) camera = move camera (-1 * sin ya, 0, -1 * cos ya)

moveBackward :: Camera -> Camera
moveBackward = rotated moveBackward'
    where moveBackward' (_, ya, _) camera = move camera (sin ya, 0, cos ya)

. , , , : move camera. , , moveForward, 3- 3-, :

moveRotated :: ((Double, Double, Double) -> (Double, Double, Double)) -> Camera -> Camera
moveRotated f camera = move camera . f $ cPosition camera

moveForward :: Camera -> Camera
moveForward = moveRotated forward
    where forward (_, ya, _) = (- sin ya, 0, - cos ya)

moveBackward :: Camera -> Camera
moveBackward = moveRotated backward
    where backward (_, ya, _) = (sin ya, 0, cos ya)

moveForward moveBackward, , -, . , - , .

+7

snd3 :: (a, b, c) -> b
snd3 (a, b, c) = b

moveForward camera = \ya -> (-1 * sin ya, 0, -1 * cos ya) $ snd3 $ cRotation camera

moveBackward camera = \ya -> (sin ya, 0, cos ya) $ snd3 $ cRotation camera

, lens , snd3 cRotation camera cRotation camera ^. _2 view _2 $ cRotation camera. , ,

apply3 :: (a -> a') -> (b -> b') -> (c -> c') -> (a, b, c) -> (a', b', c')
apply3 f1 f2 f3 (a, b, c) = (f1 a, f2 b, f3 c)

moveForward = apply3 (negate . sin) (const 0) (negate . cos) . snd3 . cRotation

moveBackward = apply3 sin (const 0) cos . snd3 . cRotation

eta-.

, 2- , 3- .

+2

All Articles