Types
Primitives
Paradox has six primitive types:
| Type | Description | Literal Examples |
|---|---|---|
|
Arbitrary-precision integers |
|
|
Unicode text strings |
|
|
Single Unicode character |
|
|
Truth values |
|
|
Double-precision floating point |
|
|
The unit type (empty value) |
|
Product Types
Product types (records) are defined with type, followed by named fields:
type Pet
name: Text
age: Integer
species: Species
Each field has a name and a type, indented under the type declaration.
Union Types
Union types (sum types / tagged unions) are defined with union, followed by named members:
union Species
cat
dog
horse
snake
Each member is a named variant of the union, indented under the union declaration. Members without payloads are simple enumerations. Members can also carry data:
union Either l r
left: l
right: r
Wrap Types
Wrap types create a new named type around an existing type, similar to Haskell’s newtype:
wrap Natural: Integer
valid Natural
unwrap >= 0
Wraps are a zero-cost abstraction in backends that support it (e.g. Haskell’s newtype), meaning the wrapper is erased at runtime with no performance overhead. In other backends (e.g. TypeScript), wraps may compile to a thin runtime wrapper.
Wraps are commonly paired with validation to create refined subtypes.
Unwrap
Every wrap type has a built-in unwrap accessor, analogous to a field on a product or a member on a union. Access the inner value with dot notation:
myNatural.unwrap // Natural -> Integer
For nested wraps, unwrap can be chained:
wrap Natural: Integer
wrap Positive: Natural
myPositive.unwrap // Positive -> Natural
myPositive.unwrap.unwrap // Positive -> Natural -> Integer
Each .unwrap peels off one layer of wrapping.
The unwrap accessor can also be used unqualified inside valid blocks, where the subject is implicit:
valid Positive
unwrap as Integer != 0
Cast Chains
As an alternative to chaining .unwrap, use as to cast through multiple wrap layers in one step:
wrap Natural: Integer
wrap Positive: Natural
valid Positive
unwrap as Integer != 0
Here Positive wraps Natural which wraps Integer. The expression unwrap as Integer casts through the chain from Positive down to Integer, equivalent to unwrap.unwrap.
For a full description of the casting system — including primitive casts, collection casts, and how the compiler resolves cast paths — see Casting.
Composite Types
Paradox has four composite type constructors:
| Syntax | Type | Example Values |
|---|---|---|
|
Array of |
|
|
Set of |
|
|
Optional |
|
|
Function from |
|
Type Parameters and Polymorphism
Type parameters are lowercase identifiers:
type Tuple a b
first: a
second: b
identity: x:a. a
x
Type variables are universally quantified. Paradox infers type parameters from usage in function signatures and type definitions.
Higher-kinded type variables are supported in interfaces:
interface for: f a. (a. b). f b
Here f is a type constructor (like [], Maybe, or Either l) and a is the element type.
See Also
-
Expressions — How to construct values and compute with types
-
Casting — The
asoperator, wrap graph resolution, and primitive casts -
Validation — Refinement types constraining values
-
Pattern Matching — Destructuring union and composite types
-
URI Types — First-class URI literals with typed request/response pairs