flix

0.77.0

Clock.flix

/*
 *  Copyright 2024 Magnus Madsen
 *
 * Use of this source code is governed by the Apache 2.0 license
 * that can be found in the LICENSE.md file.
 */

pub mod Time.Clock {

    use Time.Clock
    use Time.TimeUnit

    import java.lang.System
    import java.util.concurrent.{TimeUnit => JTimeUnit}

    ///
    /// An effect used to access the current (real-world) time.
    ///
    pub eff Clock {

        ///
        /// Returns a measure of time since the epoch in the given time unit `u`.
        ///
        def currentTime(u: TimeUnit): Int64

    }

    ///
    /// Returns the number of milliseconds since the epoch.
    ///
    /// Equivalent to `currentTime(TimeUnit.Milliseconds)`.
    ///
    pub def now(): Int64 \ Clock = Clock.currentTime(TimeUnit.Milliseconds)

    ///
    /// Handles the `Clock` effect of the given function `f`.
    ///
    /// In other words, re-interprets the `Clock` effect using the `IO` effect.
    ///
    pub def handle(f: a -> b \ ef): a -> b \ (ef - Clock) + IO = x ->
        run {
            f(x)
        } with handler Clock {
            def currentTime(u, k) = {
                let time = System.currentTimeMillis();
                let ms = JTimeUnit.MILLISECONDS;
                match u {
                    case TimeUnit.Days         => k(ms.toDays(time))
                    case TimeUnit.Hours        => k(ms.toHours(time))
                    case TimeUnit.Microseconds => k(ms.toMicros(time))
                    case TimeUnit.Milliseconds => k(ms.toMillis(time))
                    case TimeUnit.Minutes      => k(ms.toMinutes(time))
                    case TimeUnit.Nanoseconds  => k(ms.toNanos(time))
                    case TimeUnit.Seconds      => k(ms.toSeconds(time))
                }
            }
        }

    ///
    /// Runs the `Clock` effect of the given function `f`.
    ///
    /// In other words, re-interprets the `Clock` effect using the `IO` effect.
    ///
    @DefaultHandler
    pub def runWithIO(f: Unit -> a \ ef): a \ (ef - Clock) + IO = handle(f)()

}