diff --git a/geomancy.cabal b/geomancy.cabal index 710aca0ca36a75b34ce24d4cb0cc6cc2b096cc01..549a2d6d8039e8f7e0bb23e29be51bcab29f33ed 100644 --- a/geomancy.cabal +++ b/geomancy.cabal @@ -35,6 +35,7 @@ library Geomancy.IVec2 Geomancy.IVec3 Geomancy.IVec4 + Geomancy.Lens Geomancy.Mat4 Geomancy.Point Geomancy.Quaternion diff --git a/src/Geomancy/Lens.hs b/src/Geomancy/Lens.hs new file mode 100644 index 0000000000000000000000000000000000000000..35d5c8c2175c6f81f912cb1d3dcbc4786f08db44 --- /dev/null +++ b/src/Geomancy/Lens.hs @@ -0,0 +1,59 @@ +module Geomancy.Lens ( + -- * Vec2 + v2x, + v2y, + + -- * Vec3 + v3x, + v3y, + v3z, +) where + +import Geomancy.Vec2 +import Geomancy.Vec3 + +type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s + +lens :: (s -> a) -> (s -> a -> s) -> Lens' s a +lens sa sbt afb s = sbt s <$> afb (sa s) +{-# INLINE lens #-} + +v2x :: Lens' Vec2 Float +v2x = lens getv setv + where + getv :: Vec2 -> Float + getv (WithVec2 x _) = x + setv :: Vec2 -> Float -> Vec2 + setv (WithVec2 _ y) newX = vec2 newX y + +v2y :: Lens' Vec2 Float +v2y = lens getv setv + where + getv :: Vec2 -> Float + getv (WithVec2 _ y) = y + setv :: Vec2 -> Float -> Vec2 + setv (WithVec2 x _) = vec2 x + +v3x :: Lens' Vec3 Float +v3x = lens getv setv + where + getv :: Vec3 -> Float + getv (WithVec3 x _ _) = x + setv :: Vec3 -> Float -> Vec3 + setv (WithVec3 _ y z) newX = vec3 newX y z + +v3y :: Lens' Vec3 Float +v3y = lens getv setv + where + getv :: Vec3 -> Float + getv (WithVec3 _ y _) = y + setv :: Vec3 -> Float -> Vec3 + setv (WithVec3 x _ z) newY = vec3 x newY z + +v3z :: Lens' Vec3 Float +v3z = lens getv setv + where + getv :: Vec3 -> Float + getv (WithVec3 _ _ z) = z + setv :: Vec3 -> Float -> Vec3 + setv (WithVec3 x y _) = vec3 x y