{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE RankNTypes #-}
module Data.Aviation.WB.Moment(
Moment(..)
, HasMoment(..)
, HasMoments(..)
, SetMoment(..)
, HasMoment0(..)
, totalMoment
, totalMoments
, totalMoment''
, totalWeights
, momentX
) where
import Control.Applicative(Applicative((<*>)))
import Control.Category((.))
import Control.Lens(Lens', Traversal', Setter', Iso', lens, makeClassy, view, re)
import Data.Aviation.WB.Arm.ArmStatic(ArmStatic, HasArmStatic(armStatic), HasArmStatics(armStatics), SetArmStatic(setArmStatic))
import Data.Aviation.WB.Weight(Weight, HasWeight(weight), HasWeights(weights), SetWeight(setWeight))
import Data.Eq(Eq)
import Data.Foldable(Foldable, foldl, foldMap)
import Data.Functor((<$>))
import Data.Maybe(Maybe)
import Data.Ord(Ord)
import Prelude(Show, (*), (+), Rational)
data Moment =
Moment
Weight
ArmStatic
deriving (Eq, Ord, Show)
makeClassy ''Moment
class HasMoments a where
moments ::
Traversal'
a
Moment
instance HasMoments Moment where
moments =
moment
class SetMoment a where
setMoment ::
Setter'
a
Moment
instance SetMoment Moment where
setMoment =
moment
class HasMoment0 a where
moment0 ::
Lens'
a
(Maybe Moment)
instance HasWeight Moment where
weight =
lens
(\(Moment w _) -> w)
(\(Moment _ a) w -> Moment w a)
instance HasWeights Moment where
weights =
weight
instance SetWeight Moment where
setWeight =
weight
instance HasArmStatic Moment where
armStatic =
lens
(\(Moment _ a) -> a)
(\(Moment w _) a -> Moment w a)
instance HasArmStatics Moment where
armStatics =
armStatic
instance SetArmStatic Moment where
setArmStatic =
armStatic
totalMoment ::
HasMoment moment =>
Iso' Rational Weight
-> Iso' Rational ArmStatic
-> moment
-> Rational
totalMoment w a m =
let r = view (moment . weight . re w) m
s = view (moment . armStatic . re a) m
in r * s
totalMoments ::
(HasMoment moment, Foldable f) =>
Iso' Rational Weight
-> Iso' Rational ArmStatic
-> f moment
-> Rational
totalMoments w a =
foldl (\x y -> x + totalMoment w a y) 0
totalMoment'' ::
(HasMoment moment, Foldable f) =>
Iso' Rational Weight
-> Iso' Rational ArmStatic
-> f moment
-> Moment
totalMoment'' w a m =
let (mw, ma) = foldl (\(w', a') n -> let w'' = view (moment . weight . re w) n
a'' = view (moment . armStatic . re a) n
in (w' + w'', a' + w'' * a'')) (0, 0) m
in Moment (view w mw) (view a ma)
totalWeights ::
(HasMoment moment, Foldable f) =>
f moment
-> Weight
totalWeights =
foldMap (view (moment . weight))
momentX ::
(HasWeight w, HasArmStatic s, Applicative f) =>
f w
-> f s
-> f Moment
momentX wt b =
(\w -> Moment (view weight w) . view armStatic) <$> wt <*> b