zwirn-core-0.1.1.0: src/Zwirn/Core/Conditional.hs
module Zwirn.Core.Conditional where
{-
Conditional.hs - conditional functions
Copyright (C) 2025, Martin Gius
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}
import Data.Bifunctor (first)
import Data.Fixed (mod')
import Zwirn.Core.Core
import Zwirn.Core.Modulate
import Zwirn.Core.Time
import Zwirn.Core.Types
ifthen :: (MultiMonad k) => ZwirnT k st i Bool -> ZwirnT k st i a -> ZwirnT k st i a -> ZwirnT k st i a
ifthen bz xz yz = innerJoin $ zwirn q
where
q t st = first (fmap f) <$> unzwirn bz t st
where
f True = xz
f False = yz
iff :: (MultiMonad k, HasSilence k) => ZwirnT k st i Bool -> ZwirnT k st i a -> ZwirnT k st i a
iff b x = ifthen b x silence
or :: (Applicative k) => ZwirnT k st i Bool -> ZwirnT k st i Bool -> ZwirnT k st i Bool
or = liftA2 (||)
and :: (Applicative k) => ZwirnT k st i Bool -> ZwirnT k st i Bool -> ZwirnT k st i Bool
and = liftA2 (&&)
not :: (Functor k) => ZwirnT k st i Bool -> ZwirnT k st i Bool
not = fmap Prelude.not
eq :: (Eq a, Applicative k) => ZwirnT k st i a -> ZwirnT k st i a -> ZwirnT k st i Bool
eq = liftA2 (==)
leq :: (Ord a, Applicative k) => ZwirnT k st i a -> ZwirnT k st i a -> ZwirnT k st i Bool
leq = liftA2 (<=)
geq :: (Ord a, Applicative k) => ZwirnT k st i a -> ZwirnT k st i a -> ZwirnT k st i Bool
geq = liftA2 (>=)
le :: (Ord a, Applicative k) => ZwirnT k st i a -> ZwirnT k st i a -> ZwirnT k st i Bool
le = liftA2 (<)
ge :: (Ord a, Applicative k) => ZwirnT k st i a -> ZwirnT k st i a -> ZwirnT k st i Bool
ge = liftA2 (>)
while :: (MultiMonad k) => ZwirnT k st i Bool -> ZwirnT k st i (ZwirnT k st i a -> ZwirnT k st i a) -> ZwirnT k st i a -> ZwirnT k st i a
while b f x = ifthen b (squeezeApply f x) x
-- | the first value controls the period the second the length of applying the function in that period
everyFor :: (Monad k) => ZwirnT k st i Time -> ZwirnT k st i Time -> ZwirnT k st i (ZwirnT k st i a -> ZwirnT k st i a) -> ZwirnT k st i a -> ZwirnT k st i a
everyFor t1 t2 f x = everyFor' <$> t1 <*> t2 <*> f <$$> x
where
everyFor' :: (Monad k) => Time -> Time -> (ZwirnT k st i a -> ZwirnT k st i a) -> ZwirnT k st i a -> ZwirnT k st i a
everyFor' per for f x = zwirn $ \t st -> if mod' t per <= for then unzwirn (f x) t st else unzwirn x t st
-- | applies function every period for one cycle
every :: (Monad k) => ZwirnT k st i Time -> ZwirnT k st i (ZwirnT k st i a -> ZwirnT k st i a) -> ZwirnT k st i a -> ZwirnT k st i a
every x = everyFor x (pure 1)