module Data.Propagator.Num where
import Control.Monad.ST (ST)
import Data.Propagator.Cell (Cell, connect, readCell)
plus :: Num a => Cell s a -> Cell s a -> Cell s a -> ST s ()
plus left right result = do
connect left result (\lv -> (lv +) <$> readCell right)
connect left right (\lv -> subtract lv <$> readCell result)
connect right result (\rv -> (+ rv) <$> readCell left)
connect right left (\rv -> subtract rv <$> readCell result)
connect result left (\sv -> (sv -) <$> readCell right)
connect result right (\sv -> (sv -) <$> readCell left)
minus :: Num a => Cell s a -> Cell s a -> Cell s a -> ST s ()
minus left right result = do
connect left result (\lv -> (lv -) <$> readCell right)
connect left right (\lv -> (lv -) <$> readCell result)
connect right result (\rv -> subtract rv <$> readCell left)
connect right left (\rv -> (+ rv) <$> readCell result)
connect result left (\dv -> (+ dv) <$> readCell right)
connect result right (\dv -> subtract dv <$> readCell left)
times :: Num a => Cell s a -> Cell s a -> Cell s a -> ST s ()
times left right result = do
connect left result (\lv -> (lv *) <$> readCell right)
connect right result (\rv -> (* rv) <$> readCell left)
timesWith :: Num a => (a -> a -> a) -> Cell s a -> Cell s a -> Cell s a -> ST s ()
timesWith inverseTimes left right result = do
times left right result
connect left right (\lv -> (`inverseTimes` lv) <$> readCell result)
connect right left (\rv -> (`inverseTimes` rv) <$> readCell result)
connect result left (\pv -> (pv `inverseTimes`) <$> readCell right)
connect result right (\pv -> (pv `inverseTimes`) <$> readCell left)
abs :: Num a => Cell s a -> Cell s a -> ST s ()
abs cell result =
connect cell result (pure . Prelude.abs)
absWith :: Num a => (a -> a) -> Cell s a -> Cell s a -> ST s ()
absWith inverseAbs cell result = do
connect cell result (pure . Prelude.abs)
connect result cell (pure . inverseAbs)
negate :: Num a => Cell s a -> Cell s a -> ST s ()
negate cell result = do
connect cell result (pure . Prelude.negate)
connect result cell (pure . Prelude.negate)
signum :: Num a => Cell s a -> Cell s a -> ST s ()
signum cell result =
connect cell result (pure . Prelude.signum)
signumWith :: Num a => (a -> a) -> Cell s a -> Cell s a -> ST s ()
signumWith inverseSignum cell result = do
connect cell result (pure . Prelude.signum)
connect result cell (pure . inverseSignum)