liveBook · Manning

Unit type

As explained in F# in Action: A Revised Edition of Get Programming with F#

Unit is an F# type representing the absence of a meaningful result while still providing a value for every expression and function.

Unit is F#’s value for the absence of a meaningful value. It is written as (), has the type unit, and lets every expression and function still produce a value. A function that prints, writes, or otherwise performs an action commonly returns unit rather than a useful result. section 4.1.6 section 6.1.1

This differs from void: unit is an ordinary value that can be returned or bound to a name. F# converts between unit and void when calling .NET Framework Class Library APIs, so void-returning .NET methods appear as unit-returning functions in F#. section 4.1.6

Use unit in two complementary places:

  • As an output, signal that a function completed an action but has no meaningful result. A signature such as int -> unit means the function accepts an integer and performs an effect such as console output. section 4.1.6
  • As an input, write () when a function needs no specific argument but must run anew on each call. This distinguishes a callable computation from a value calculated once during binding. section 4.1.6
  • When deliberately discarding a meaningful result in a sequence of actions, use ignore. It turns any value into unit and makes that discard explicit to the compiler. section 4.1.7

Recalculate current time on each call

let getTheCurrentTime = System.DateTime.Now binds one time value, so later uses copy that original value. Define let getTheCurrentTime () = System.DateTime.Now instead, then call getTheCurrentTime () each time a fresh evaluation is wanted. The () input says no data is required, not that no call occurs. section 4.1.6

Seeing unit in an input or output is a useful clue that code interacts with the outside world or exists to sequence actions. Prefer returning useful values when later code needs them; expression-oriented code composes those results directly. For a unit-returning conditional action, F# can omit an else () branch. section 4.1.4 section 8.2.5

let getTheCurrentTime () = System.DateTime.Now    #1
let x = getTheCurrentTime ()                      #2
let y = getTheCurrentTime ()                      #2

Compare a bound DateTime value with a function taking (). The latter is called explicitly, making repeated evaluation visible at each use. section 4.1.6

How F# in Action: A Revised Edition of Get Programming with F# covers it

How deep it goes
Defines unit values, input and output signatures, void conversion, repeated evaluation, and explicit discarding with ignore.
Examples
Uses console addition, current-time retrieval, date addition, and conditionally saving an OrderRequest.
What it assumes
Introduces unit from zero while assuming only the need for functions that print, write, or call .NET APIs.
What you can do after
Apply it via F# function signatures to model actions, invoke no-argument computations, and explicitly discard unwanted results.
How it connects
Connects unit to expressions, side effects, ignore, immutability, currying, pipelines, and if/then/else.

Also explained in

Compare how 7 books explain unit type →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of F# in Action: A Revised Edition of Get Programming with F#. The section links point to the parts of the book it draws on.