Поиск…


Что хорошего в 0-кортеже?

Набор из 2-х кортежей или 3-кортежей представляет собой группу связанных предметов. (Точки в 2D-пространстве, RGB-значения цвета и т. Д.). 1-кортеж не очень полезен, поскольку его можно легко заменить одним int .

0-кортеж кажется еще более бесполезным, поскольку в нем нет абсолютно ничего . Тем не менее он обладает свойствами, которые делают его очень полезным в функциональных языках, таких как F #. Например, тип 0-кортежа имеет ровно одно значение, обычно представленное как () . Все 0-кортежи имеют это значение, поэтому он по существу является одноэлементным. В большинстве функциональных языков программирования, включая F #, это называется типом unit .

Функции, возвращающие void в C #, возвращают тип unit в F #:

let printResult = printfn "Hello"

Запустите это в интерактивном интерпретаторе F #, и вы увидите:

val printResult : unit = ()

Это означает, что значение printResult имеет тип unit и имеет значение () (пустой кортеж, одно и единственное значение типа unit ).

Функции также могут принимать тип unit в качестве параметра. В F # функции могут выглядеть так, как будто они не принимают никаких параметров. Но на самом деле они берут единственный параметр unit типа. Эта функция:

let doMath() = 2 + 4

на самом деле эквивалентно:

let doMath () = 2 + 4

То есть, функция, которая принимает один параметр unit типа и возвращает значение int 6. Если вы посмотрите на подпись типа, которую интерпретирует интерактивный интерпретатор F # при определении этой функции, вы увидите:

val doMath : unit -> int

Тот факт, что все функции будут принимать по крайней мере один параметр и возвращать значение, даже если это значение иногда является «бесполезным» значением like () , означает, что композиция функций намного проще в F #, чем на языках, на которых нет тип unit . Но это более продвинутый предмет, о котором мы поговорим позже. Пока просто помните, что когда вы видите unit в сигнатуре функции или () в параметрах функции, это тип 0-кортежа, который служит в качестве способа сказать: «Эта функция принимает или возвращает значения, значимые».

Отложить выполнение кода

Мы можем использовать тип unit в качестве аргумента функции для определения функций, которые мы не хотим выполнять до конца. Это часто полезно в асинхронных фоновых задачах, когда основной поток может запускать некоторые предопределенные функции фонового потока, например, может быть, переместить его в новый файл или если aa let-binding не следует запускать сразу:

module Time =
    let now = System.DateTime.Now   // value is set and fixed for duration of program
    let now() = System.DateTime.Now // value is calculated when function is called (each time)

В следующем коде мы определяем код для запуска «рабочего», который просто выводит значение, которое он работает каждые 2 секунды. Затем рабочий возвращает две функции, которые могут использоваться для управления им - одна, которая перемещает ее до следующего значения для работы, и которое перестает работать. Они должны быть функциями, потому что мы не хотим, чтобы их тела исполнялись до тех пор, пока мы не примем решение, иначе рабочий немедленно переместится ко второму значению и выключится, не сделав ничего.

let startWorker value =
    let current = ref value
    let stop = ref false
    let nextValue () = current := !current + 1
    let stopOnNextTick () = stop := true
    let rec loop () = async {
        if !stop then
            printfn "Stopping work."
            return ()
        else
            printfn "Working on %d." !current
            do! Async.Sleep 2000
            return! loop () }
    Async.Start (loop ())
    nextValue, stopOnNextTick

Затем мы можем начать работника,

let nextValue, stopOnNextTick = startWorker 12

и работа начнется - если мы находимся в интерактивном режиме F #, мы увидим, что сообщения печатаются на консоли каждые две секунды. Затем мы можем запустить

nextValue ()

и мы увидим сообщения, указывающие, что обрабатываемая ценность переместилась на следующую.

Когда пришло время закончить работу, мы можем запустить

stopOnNextTick ()

функция, которая распечатает закрывающее сообщение, затем выйдет.

unit типа важно здесь не означает «нет» вход - функции уже есть вся информация , они должны работать встроенные в них, и вызывающий абонент не может изменить.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow