Оглавление > Интервальный таймер на F#
01.02.2023

Создание интервального таймера на языке F#

Постановка задачи

Для слежения за временем понадобились часы, которые будут издавать сигнал каждые 15 минут, например в 8:00, 8:15, 8:30 и так далее до конца света или закрытия программы.

Императивный подход

  1. Бойлерплэйт
open System
  1. Организуем бесконечный цикл
while true do
  1. Вычисляем ближайшую четверть часа
  let time0 = DateTime.Now
  let span = new TimeSpan(0, time0.Minute % 15, time0.Second)
  let next = (time0 - span).AddMinutes 15.0
  1. спим до ее наступления и сигналим
  printf $"{next}"

  while next > DateTime.Now do
      Threading.Thread.Sleep 1000

  Console.Beep()
  printfn " - ok"
  1. все повторяется сначала благодаря while

Функциональный подход

  1. Бойлерплэйт
open System
  1. Генерируем бесконечную последовательность "будильников"
let time0 = DateTime.Now
let span = new TimeSpan(0, time0.Minute % 15, time0.Second)
let time_seq = time0 - span |> Seq.unfold (fun s -> Some(s, s.AddMinutes 15.0))
  1. объявляем функцию, которая спит до наступления времени и сигналит
let beeper t =
    printf $"{t}"

    if t > DateTime.Now then //только если будильник в будущем
        while t > DateTime.Now do //спим пока не наступит
            Threading.Thread.Sleep 1000

        Console.Beep() //сигналим
        printfn " - ok"
    else //если будильник оказался в прошлом, например после спящего режима
        printfn " - skip"
  1. применяем эту функцию к элементам последовательности
time_seq |> Seq.iter beeper