packages feed

rhine 0.7.1 → 0.8.0.0

raw patch · 22 files changed

+131/−99 lines, 22 filesdep +time-domaindep ~basedep ~dunaiPVP ok

version bump matches the API change (PVP)

Dependencies added: time-domain

Dependency ranges changed: base, dunai

API changes (from Hackage documentation)

- FRP.Rhine: data Empty
- FRP.Rhine.ClSF.Except: data Empty
- FRP.Rhine.Clock: instance (GHC.Base.Monad m, FRP.Rhine.TimeDomain.TimeDomain time, FRP.Rhine.Clock.Clock m cl) => FRP.Rhine.Clock.Clock m (FRP.Rhine.Clock.RescaledClock cl time)
- FRP.Rhine.Clock: instance (GHC.Base.Monad m, FRP.Rhine.TimeDomain.TimeDomain time, FRP.Rhine.Clock.Clock m cl) => FRP.Rhine.Clock.Clock m (FRP.Rhine.Clock.RescaledClockM m cl time)
- FRP.Rhine.Clock: instance (GHC.Base.Monad m, FRP.Rhine.TimeDomain.TimeDomain time, FRP.Rhine.Clock.Clock m cl) => FRP.Rhine.Clock.Clock m (FRP.Rhine.Clock.RescaledClockS m cl time tag)
- FRP.Rhine.TimeDomain: NumTimeDomain :: a -> NumTimeDomain a
- FRP.Rhine.TimeDomain: [fromNumTimeDomain] :: NumTimeDomain a -> a
- FRP.Rhine.TimeDomain: class TimeDomain time where {
- FRP.Rhine.TimeDomain: data UTCTime
- FRP.Rhine.TimeDomain: diffTime :: TimeDomain time => time -> time -> Diff time
- FRP.Rhine.TimeDomain: instance FRP.Rhine.TimeDomain.TimeDomain ()
- FRP.Rhine.TimeDomain: instance FRP.Rhine.TimeDomain.TimeDomain Data.Time.Clock.Internal.UTCTime.UTCTime
- FRP.Rhine.TimeDomain: instance FRP.Rhine.TimeDomain.TimeDomain GHC.Integer.Type.Integer
- FRP.Rhine.TimeDomain: instance FRP.Rhine.TimeDomain.TimeDomain GHC.Types.Double
- FRP.Rhine.TimeDomain: instance FRP.Rhine.TimeDomain.TimeDomain GHC.Types.Float
- FRP.Rhine.TimeDomain: instance GHC.Num.Num a => FRP.Rhine.TimeDomain.TimeDomain (FRP.Rhine.TimeDomain.NumTimeDomain a)
- FRP.Rhine.TimeDomain: instance GHC.Num.Num a => GHC.Num.Num (FRP.Rhine.TimeDomain.NumTimeDomain a)
- FRP.Rhine.TimeDomain: newtype NumTimeDomain a
- FRP.Rhine.TimeDomain: type family Diff time;
- FRP.Rhine.TimeDomain: }
+ FRP.Rhine: (>--^) :: (Clock m (Out cl), Time cl ~ Time (Out cl)) => SN m cl a b -> ClSF m (Out cl) b c -> SN m cl a c
+ FRP.Rhine: (@>-^) :: (Clock m (Out cl), Time cl ~ Time (Out cl)) => Rhine m cl a b -> ClSF m (Out cl) b c -> Rhine m cl a c
+ FRP.Rhine: (@>>^) :: Monad m => Rhine m cl a b -> (b -> c) -> Rhine m cl a c
+ FRP.Rhine: (^-->) :: (Clock m (In cl), Time cl ~ Time (In cl)) => ClSF m (In cl) a b -> SN m cl b c -> SN m cl a c
+ FRP.Rhine: (^->@) :: (Clock m (In cl), Time cl ~ Time (In cl)) => ClSF m (In cl) a b -> Rhine m cl b c -> Rhine m cl a c
+ FRP.Rhine: (^>>@) :: Monad m => (a -> b) -> Rhine m cl b c -> Rhine m cl a c
+ FRP.Rhine: [Postcompose] :: (Clock m (Out cl), Time cl ~ Time (Out cl)) => SN m cl a b -> ClSF m (Out cl) b c -> SN m cl a c
+ FRP.Rhine: [Precompose] :: (Clock m (In cl), Time cl ~ Time (In cl)) => ClSF m (In cl) a b -> SN m cl b c -> SN m cl a c
+ FRP.Rhine: class TimeDifference d
+ FRP.Rhine: difference :: TimeDifference d => d -> d -> d
+ FRP.Rhine.ClSF.Core: class TimeDifference d
+ FRP.Rhine.ClSF.Core: difference :: TimeDifference d => d -> d -> d
+ FRP.Rhine.Clock: class TimeDifference d
+ FRP.Rhine.Clock: difference :: TimeDifference d => d -> d -> d
+ FRP.Rhine.Clock: instance (GHC.Base.Monad m, Data.TimeDomain.TimeDomain time, FRP.Rhine.Clock.Clock m cl) => FRP.Rhine.Clock.Clock m (FRP.Rhine.Clock.RescaledClock cl time)
+ FRP.Rhine.Clock: instance (GHC.Base.Monad m, Data.TimeDomain.TimeDomain time, FRP.Rhine.Clock.Clock m cl) => FRP.Rhine.Clock.Clock m (FRP.Rhine.Clock.RescaledClockM m cl time)
+ FRP.Rhine.Clock: instance (GHC.Base.Monad m, Data.TimeDomain.TimeDomain time, FRP.Rhine.Clock.Clock m cl) => FRP.Rhine.Clock.Clock m (FRP.Rhine.Clock.RescaledClockS m cl time tag)
+ FRP.Rhine.Clock.Select: instance (GHC.Base.Monoid cl, GHC.Base.Semigroup a) => GHC.Base.Monoid (FRP.Rhine.Clock.Select.SelectClock cl a)
+ FRP.Rhine.Clock.Select: instance (GHC.Base.Semigroup a, GHC.Base.Semigroup cl) => GHC.Base.Semigroup (FRP.Rhine.Clock.Select.SelectClock cl a)
+ FRP.Rhine.Reactimation.Combinators: (@>-^) :: (Clock m (Out cl), Time cl ~ Time (Out cl)) => Rhine m cl a b -> ClSF m (Out cl) b c -> Rhine m cl a c
+ FRP.Rhine.Reactimation.Combinators: (@>>^) :: Monad m => Rhine m cl a b -> (b -> c) -> Rhine m cl a c
+ FRP.Rhine.Reactimation.Combinators: (^->@) :: (Clock m (In cl), Time cl ~ Time (In cl)) => ClSF m (In cl) a b -> Rhine m cl b c -> Rhine m cl a c
+ FRP.Rhine.Reactimation.Combinators: (^>>@) :: Monad m => (a -> b) -> Rhine m cl b c -> Rhine m cl a c
+ FRP.Rhine.SN: [Postcompose] :: (Clock m (Out cl), Time cl ~ Time (Out cl)) => SN m cl a b -> ClSF m (Out cl) b c -> SN m cl a c
+ FRP.Rhine.SN: [Precompose] :: (Clock m (In cl), Time cl ~ Time (In cl)) => ClSF m (In cl) a b -> SN m cl b c -> SN m cl a c
+ FRP.Rhine.SN.Combinators: (>--^) :: (Clock m (Out cl), Time cl ~ Time (Out cl)) => SN m cl a b -> ClSF m (Out cl) b c -> SN m cl a c
+ FRP.Rhine.SN.Combinators: (^-->) :: (Clock m (In cl), Time cl ~ Time (In cl)) => ClSF m (In cl) a b -> SN m cl b c -> SN m cl a c
- FRP.Rhine: class TimeDomain time where {
+ FRP.Rhine: class TimeDifference Diff time => TimeDomain time where {
- FRP.Rhine: safely :: forall (m :: Type -> Type) a b. Monad m => MSFExcept m a b Empty -> MSF m a b
+ FRP.Rhine: safely :: forall (m :: Type -> Type) a b. Monad m => MSFExcept m a b Void -> MSF m a b
- FRP.Rhine.ClSF.Core: class TimeDomain time where {
+ FRP.Rhine.ClSF.Core: class TimeDifference Diff time => TimeDomain time where {
- FRP.Rhine.ClSF.Except: safely :: forall (m :: Type -> Type) a b. Monad m => MSFExcept m a b Empty -> MSF m a b
+ FRP.Rhine.ClSF.Except: safely :: forall (m :: Type -> Type) a b. Monad m => MSFExcept m a b Void -> MSF m a b
- FRP.Rhine.Clock: -- | Additional information that the clock may output at each tick, e.g. if
+ FRP.Rhine.Clock: -- | The type of differences or durations between two timestamps
- FRP.Rhine.Clock: class TimeDomain time where {
+ FRP.Rhine.Clock: class TimeDifference Diff time => TimeDomain time where {

Files

ChangeLog.md view
@@ -4,10 +4,14 @@ Since `rhine` reexports modules from `dunai`, every major version in `dunai` triggers a major version in `rhine`. -## 0.7.1+## 0.8.0.0  * Documentation improvements * Support for GHC 9.0.2+* Updated to `dunai-0.8`+* Added functions to pre-/post-compose SNs and Rhines with ClSFs+* Added flake & stack support on CI.+  Thank you, Miguel Negrão and Jun Matsuhita!  ## 0.7.0 
rhine.cabal view
@@ -1,6 +1,6 @@ name:                rhine -version:             0.7.1+version:             0.8.0.0  synopsis: Functional Reactive Programming with type-level clocks @@ -46,7 +46,7 @@ source-repository this   type:     git   location: git@github.com:turion/rhine.git-  tag:      v0.7.1+  tag:      v0.8.0.0   library@@ -88,7 +88,6 @@     FRP.Rhine.Schedule.Trans     FRP.Rhine.SN     FRP.Rhine.SN.Combinators-    FRP.Rhine.TimeDomain     FRP.Rhine.Type    other-modules:@@ -100,8 +99,8 @@   -- other-extensions:    -- Other library packages from which modules are imported.-  build-depends:       base         >= 4.11 && < 4.16-                     , dunai        >= 0.6+  build-depends:       base         >= 4.13 && < 4.16+                     , dunai        >= 0.8                      , transformers >= 0.5                      , time         >= 1.8                      , free         >= 5.1@@ -111,16 +110,24 @@                      , random       >= 1.1                      , MonadRandom  >= 0.5                      , simple-affine-space+                     , time-domain    -- Directories containing source files.   hs-source-dirs:      src -  ghc-options:         -Wall-                       -Wno-unticked-promoted-constructors-                       -Wno-type-defaults+  ghc-options:  -W+                -Wno-unticked-promoted-constructors +  if flag(dev)+    ghc-options: -Werror+   if impl(ghc >= 8.6)     default-extensions: NoStarIsType    -- Base language which the package is written in.   default-language:    Haskell2010++flag dev+  description: Enable warnings as errors. Active on ci.+  default: False+  manual: True
src/FRP/Rhine/ClSF/Core.hs view
@@ -23,7 +23,6 @@ import Control.Monad.Trans.Reader (ReaderT, mapReaderT, withReaderT)  -- dunai-import Data.MonadicStreamFunction (MSF, arrM, constM, morphS, liftTransS) import Data.MonadicStreamFunction as X hiding ((>>>^), (^>>>))  -- rhine
src/FRP/Rhine/ClSF/Except.hs view
@@ -12,7 +12,7 @@ module FRP.Rhine.ClSF.Except   ( module FRP.Rhine.ClSF.Except   , module X-  , safe, safely, Empty, exceptS, runMSFExcept, currentInput+  , safe, safely, exceptS, runMSFExcept, currentInput   )   where 
src/FRP/Rhine/ClSF/Random.hs view
@@ -15,9 +15,6 @@ -- transformers import Control.Monad.IO.Class --- random-import System.Random (newStdGen)- -- MonadRandom import Control.Monad.Random 
src/FRP/Rhine/ClSF/Upsample.hs view
@@ -6,12 +6,8 @@  module FRP.Rhine.ClSF.Upsample where --- base-import Data.Semigroup- -- dunai import Control.Monad.Trans.MSF.Reader---import Data.MonadicStreamFunction  -- rhine import FRP.Rhine.ClSF.Core
src/FRP/Rhine/ClSF/Util.hs view
@@ -29,7 +29,6 @@  -- dunai import Control.Monad.Trans.MSF.Reader (readerS)-import Data.MonadicStreamFunction (constM, sumFrom, iPre, feedback) import Data.MonadicStreamFunction.Instances.VectorSpace ()  -- simple-affine-space
src/FRP/Rhine/Clock.hs view
@@ -31,8 +31,8 @@ -- dunai import Data.MonadicStreamFunction as X hiding ((>>>^), (^>>>)) --- rhine-import FRP.Rhine.TimeDomain as X+-- time-domain+import Data.TimeDomain as X  -- * The 'Clock' type class 
src/FRP/Rhine/Clock/Periodic.hs view
@@ -17,7 +17,6 @@ module FRP.Rhine.Clock.Periodic (Periodic (Periodic)) where  -- base-import Control.Monad (forever) import Data.List.NonEmpty hiding (unfold) import Data.Maybe (fromMaybe) import GHC.TypeLits (Nat, KnownNat, natVal)
src/FRP/Rhine/Clock/Proxy.hs view
@@ -28,12 +28,12 @@  inProxy :: ClockProxy cl -> ClockProxy (In cl) inProxy LeafProxy = LeafProxy-inProxy (SequentialProxy p1 p2) = inProxy p1+inProxy (SequentialProxy p1 _) = inProxy p1 inProxy (ParallelProxy pL pR) = ParallelProxy (inProxy pL) (inProxy pR)  outProxy :: ClockProxy cl -> ClockProxy (Out cl) outProxy LeafProxy = LeafProxy-outProxy (SequentialProxy p1 p2) = outProxy p2+outProxy (SequentialProxy _ p2) = outProxy p2 outProxy (ParallelProxy pL pR) = ParallelProxy (outProxy pL) (outProxy pR)  -- | Return the incoming tag, assuming that the incoming clock is ticked,
src/FRP/Rhine/Clock/Realtime/Event.hs view
@@ -33,7 +33,6 @@ -- base import Control.Concurrent.Chan import Data.Time.Clock-import Data.Semigroup  -- deepseq import Control.DeepSeq
src/FRP/Rhine/Clock/Realtime/Stdin.hs view
@@ -9,9 +9,8 @@ {-# LANGUAGE TypeFamilies #-} module FRP.Rhine.Clock.Realtime.Stdin where --- base+-- time import Data.Time.Clock-import Data.Semigroup  -- transformers import Control.Monad.IO.Class@@ -19,7 +18,6 @@ -- rhine import FRP.Rhine.Clock import FRP.Rhine.Clock.Proxy-import Data.Semigroup  {- | A clock that ticks for every line entered on the console,
src/FRP/Rhine/Clock/Select.hs view
@@ -24,7 +24,6 @@  -- base import Data.Maybe (catMaybes, maybeToList)-import Data.Semigroup  -- | A clock that selects certain subevents of type 'a', --   from the tag of a main clock.@@ -38,6 +37,18 @@   --   or 'Just a' if the subclock should tick, with tag 'a'.   , select    :: Tag cl -> Maybe a   }++instance (Semigroup a, Semigroup cl) => Semigroup (SelectClock cl a) where+  cl1 <> cl2 = SelectClock+    { mainClock = mainClock cl1 <> mainClock cl2+    , select = \tag -> select cl1 tag <> select cl2 tag+    }++instance (Monoid cl, Semigroup a) => Monoid (SelectClock cl a) where+  mempty = SelectClock+    { mainClock = mempty+    , select = const mempty+    }   instance (Monad m, Clock m cl) => Clock m (SelectClock cl a) where
src/FRP/Rhine/Clock/Util.hs view
@@ -2,10 +2,12 @@ {-# LANGUAGE RecordWildCards #-} module FRP.Rhine.Clock.Util where +-- time-domain+import Data.TimeDomain+ -- rhine import FRP.Rhine.Clock import FRP.Rhine.Clock.Proxy-import FRP.Rhine.TimeDomain  -- * Auxiliary definitions and utilities 
src/FRP/Rhine/Reactimation.hs view
@@ -8,10 +8,6 @@ {-# LANGUAGE RecordWildCards #-} module FRP.Rhine.Reactimation where --- base-import Control.Monad ((>=>))-import Data.Functor (void)- -- dunai import Data.MonadicStreamFunction.InternalCore @@ -19,12 +15,9 @@ import FRP.Rhine.Clock import FRP.Rhine.Clock.Proxy import FRP.Rhine.ClSF.Core-import FRP.Rhine.Reactimation.ClockErasure import FRP.Rhine.Reactimation.Combinators import FRP.Rhine.Schedule import FRP.Rhine.Type--  -- * Running a Rhine 
src/FRP/Rhine/Reactimation/ClockErasure.hs view
@@ -13,12 +13,10 @@  -- base import Control.Monad (join)-import Data.Maybe (fromJust, fromMaybe)  -- dunai import Control.Monad.Trans.MSF.Reader import Data.MonadicStreamFunction-import Data.MonadicStreamFunction.InternalCore  -- rhine import FRP.Rhine.Clock@@ -26,7 +24,6 @@ import FRP.Rhine.Clock.Util import FRP.Rhine.ClSF hiding (runReaderS) import FRP.Rhine.ResamplingBuffer-import FRP.Rhine.Schedule import FRP.Rhine.SN  -- | Run a clocked signal function as a monadic stream function,@@ -86,6 +83,20 @@   case tag of     Left  tagL -> eraseClockSN initialTime snL -< (time, tagL, maybeA)     Right tagR -> eraseClockSN initialTime snR -< (time, tagR, maybeA)++eraseClockSN initialTime (Postcompose sn clsf) =+  let+    proxy = toClockProxy sn+  in proc input@(time, tag, _) -> do+  bMaybe <- eraseClockSN initialTime sn -< input+  mapMaybeS $ eraseClockClSF (outProxy proxy) initialTime clsf -< (time, , ) <$> outTag proxy tag <*> bMaybe++eraseClockSN initialTime (Precompose clsf sn) =+  let+    proxy = toClockProxy sn+  in proc (time, tag, aMaybe) -> do+  bMaybe <- mapMaybeS $ eraseClockClSF (inProxy proxy) initialTime clsf -< (time, , ) <$> inTag proxy tag <*> aMaybe+  eraseClockSN initialTime sn -< (time, tag, bMaybe)  -- | Translate a resampling buffer into a monadic stream function. --
src/FRP/Rhine/Reactimation/Combinators.hs view
@@ -191,3 +191,40 @@        -> Rhine m (ParallelClock   m clL clR) a b RhineParallelAndSchedule (Rhine sn1 clL) schedule @|| (Rhine sn2 clR)   = Rhine (sn1 |||| sn2) (ParallelClock clL clR schedule)+++-- | Postcompose a 'Rhine' with a pure function.+(@>>^)+  :: Monad m+  => Rhine m cl a b+  ->             (b -> c)+  -> Rhine m cl a      c+Rhine sn cl @>>^ f = Rhine (sn >>>^ f) cl++-- | Precompose a 'Rhine' with a pure function.+(^>>@)+  :: Monad m+  =>           (a -> b)+  -> Rhine m cl      b c+  -> Rhine m cl a      c+f ^>>@ Rhine sn cl = Rhine (f ^>>> sn) cl++-- | Postcompose a 'Rhine' with a 'ClSF'.+(@>-^)+  :: ( Clock m (Out cl)+     , Time cl ~ Time (Out cl)+     )+  => Rhine m      cl  a b+  -> ClSF  m (Out cl)   b c+  -> Rhine m      cl  a   c+Rhine sn cl @>-^ clsf = Rhine (sn >--^ clsf) cl++-- | Precompose a 'Rhine' with a 'ClSF'.+(^->@)+  :: ( Clock m (In cl)+     , Time cl ~ Time (In cl)+     )+  => ClSF  m (In cl) a b+  -> Rhine m     cl    b c+  -> Rhine m     cl  a   c+clsf ^->@ Rhine sn cl = Rhine (clsf ^--> sn) cl
src/FRP/Rhine/ResamplingBuffer.hs view
@@ -18,9 +18,6 @@ -- rhine import FRP.Rhine.Clock --- base-import Control.Arrow (second)- -- A quick note on naming conventions, to whoever cares: -- . Call a single clock @cl@. -- . Call several clocks @cl1@, @cl2@ etc. in most situations.
src/FRP/Rhine/SN.hs view
@@ -69,6 +69,22 @@     => SN m                  cl1      a b     -> SN m                      cl2  a b     -> SN m (ParallelClock m cl1 cl2) a b+  -- | A 'ClSF' can always be postcomposed onto an 'SN' if the clocks match on the output.+  Postcompose+    :: ( Clock m (Out cl)+       , Time cl ~ Time (Out cl)+       )+    => SN    m      cl  a b+    -> ClSF  m (Out cl)   b c+    -> SN    m      cl  a   c+  -- | A 'ClSF' can always be precomposed onto an 'SN' if the clocks match on the input.+  Precompose+    :: ( Clock m (In cl)+       , Time cl ~ Time (In cl)+       )+    => ClSF m (In cl) a b+    -> SN   m     cl    b c+    -> SN   m     cl  a   c  instance GetClockProxy cl => ToClockProxy (SN m cl a b) where   type Cl (SN m cl a b) = cl
src/FRP/Rhine/SN/Combinators.hs view
@@ -24,7 +24,8 @@ Synchronous clsf      >>>^ f = Synchronous $ clsf >>^ f Sequential sn1 rb sn2 >>>^ f = Sequential sn1 rb     $ sn2 >>>^ f Parallel   sn1    sn2 >>>^ f = Parallel  (sn1 >>>^ f) (sn2 >>>^ f)-+Postcompose sn clsf >>>^ f = Postcompose sn $ clsf >>^ f+Precompose clsf sn >>>^ f = Precompose clsf $ sn >>>^ f  -- | Precompose a signal network with a pure function. (^>>>)@@ -35,7 +36,28 @@ f ^>>> Synchronous clsf      = Synchronous $ f ^>> clsf f ^>>> Sequential sn1 rb sn2 = Sequential (f ^>>> sn1) rb      sn2 f ^>>> Parallel   sn1    sn2 = Parallel   (f ^>>> sn1) (f ^>>> sn2)+f ^>>> Postcompose sn clsf = Postcompose (f ^>>> sn) clsf+f ^>>> Precompose clsf sn = Precompose (f ^>> clsf) sn +-- | Postcompose a signal network with a 'ClSF'.+(>--^)+  :: ( Clock m (Out cl)+     , Time cl ~ Time (Out cl)+     )+  => SN    m      cl  a b+  -> ClSF  m (Out cl)   b c+  -> SN    m      cl  a   c+(>--^) = Postcompose++-- | Precompose a signal network with a 'ClSF'.+(^-->)+  :: ( Clock m (In cl)+     , Time cl ~ Time (In cl)+     )+  => ClSF m (In cl) a b+  -> SN   m     cl    b c+  -> SN   m     cl  a   c+(^-->) = Precompose  -- | Compose two signal networks on the same clock in data-parallel. --   At one tick of @cl@, both networks are stepped.
src/FRP/Rhine/Schedule.hs view
@@ -21,9 +21,6 @@  module FRP.Rhine.Schedule where --- base-import Data.Semigroup- -- transformers import Control.Monad.Trans.Reader 
− src/FRP/Rhine/TimeDomain.hs
@@ -1,52 +0,0 @@-{- |-This module defines the 'TimeDomain' class.-Its instances model time.-Several instances such as 'UTCTime', 'Double' and 'Integer' are supplied here.--}--{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE TypeFamilies #-}-module FRP.Rhine.TimeDomain-  ( module FRP.Rhine.TimeDomain-  , UTCTime-  )-  where---- time-import Data.Time.Clock (UTCTime, diffUTCTime)---- | A time domain is an affine space representing a notion of time,---   such as real time, simulated time, steps, or a completely different notion.-class TimeDomain time where-  type Diff time-  diffTime :: time -> time -> Diff time---instance TimeDomain UTCTime where-  type Diff UTCTime = Double-  diffTime t1 t2 = realToFrac $ diffUTCTime t1 t2--instance TimeDomain Double where-  type Diff Double = Double-  diffTime = (-)--instance TimeDomain Float where-  type Diff Float = Float-  diffTime = (-)--instance TimeDomain Integer where-  type Diff Integer = Integer-  diffTime          = (-)--instance TimeDomain () where-  type Diff () = ()-  diffTime _ _ = ()---- | Any 'Num' can be wrapped to form a 'TimeDomain'.-newtype NumTimeDomain a = NumTimeDomain { fromNumTimeDomain :: a }-  deriving Num--instance Num a => TimeDomain (NumTimeDomain a) where-  type Diff (NumTimeDomain a) = NumTimeDomain a-  diffTime = (-)