git.iko.soy/rowtype-yoga/purescript-native
on eded2bd help sign in
158 lines 5.0 kB history raw
1Types
2=====
4The type system defines the following types:
6- Primitive Types: Number, String, Boolean
7- Arrays
8- Records
9- Tagged Unions
10- Functions
11- Polymorphic Types
12- Constrained Types
13- Type Synonyms
14- Rows
16Primitive Types
17---------------
19The three primitive types ``String``, ``Number`` and ``Boolean`` correspond to their Javascript equivalents at runtime.
21Arrays
22------
24PureScript arrays correspond to Javascript arrays at runtime, but all elements in an array must have the same type.
26Records
27-------
29PureScript records correspond to Javascript objects. They may have zero or more named fields, each with their own types.
31Tagged Unions
32-------------
34Tagged unions consist of one or more constructors, each of which takes zero or more arguments.
36Tagged unions can only be created using their constructors, and deconstructed through pattern matching (see later).
38For example::
40 data Foo a = Foo | Bar String
42 runFoo Foo = "It's a Foo"
43 runFoo (Bar s) = "It's a Bar. The string is " ++ s
45 test = runFoo Foo ++ runFoo (Bar "Test")
47In the example, Foo is a tagged union type which has two constructors. It's first constructor ``Foo`` takes no argument, and it's second ``Bar`` takes one, which must be a String.
49``runFoo`` is an example of pattern matching on a tagged union type to discover its constructor, and the last line shows how to construct values of type ``Foo``.
51Functions
52---------
54Functions in PureScript are like their Javascript counterparts, but always have exactly one argument.
56Polymorphic Types
57-----------------
59Expressions defined at the top level may have polymorphic types.
61Here is an example::
63 identity x = x
65``identity`` is inferred to have (polymorphic) type ``forall t0. t0 -> t0``. This means that for any type ``t0``, ``identity`` can be given a value of type ``t0`` and will give back a value of the same type.
67A type annotation can also be provided::
69 identity :: forall a. a -> a
70 identity x = x
72Row Polymorphism
73----------------
75Polymorphism is not limited to abstracting over types. Values may also be polymorphic in types with other kinds, such as rows or effects (see "Kind System").
77For example, the following function accesses two properties on a record::
79 addProps o = o.foo + o.bar
81The inferred type of ``addProps`` is::
83 forall r. { foo :: Number, bar :: Number | r } -> Number
85Here, the type variable ``r`` has kind ``# *`` - it represents a `row` of `types`. It can be instantiated with any row of named types.
87In other words, ``addProps`` accepts any record which has properties ``Foo`` and ``Bar``, and *any other record properties*.
89Therefore, the following application compiles::
91 addProps { foo: 1, bar: 2, baz: 3 }
93even though the type of ``addProps`` does not mention the property ``baz``. However, the following does not compile::
95 addProps { foo: 1 }
97since the ``bar`` property is missing.
99Rank N Types
100------------
102It is also possible for the ``forall`` quantifier to appear on the left of a function arrow, inside types record fields and data constructors, and in type synonyms.
104In most cases, a type annotation is necessary when using this feature.
106As an example, we can pass a polymorphic function as an argument to another function::
108 poly :: (forall a. a -> a) -> Boolean
109 poly f = (f 0 < 1) == f true
111Notice that the polymorphic function's type argument is instantiated to both ``Number`` and ``Boolean``.
113An argument to ``poly`` must indeed be polymorphic. For example, the following fails::
115 test = poly (\n -> n + 1)
117since the skolemized type variable ``a`` does not unify with ``Number``.
119Rows
120----
122A row of types represents an unordered collection of named types without duplicates.
124Rows have kind ``# k`` for some kind ``k``, and so values do not have types which are rows. Rather, rows can be used in type signatures to define record types or other type where labelled, unordered types are useful.
126To denote a closed row, separate the fields with commas, with each label separated from its type with a double colon::
128 (name :: String, age :: Number)
130It may be necessary, depending on the context, to surround a row in parentheses.
132To denote an open row (i.e. one which may unify with another row to add new fields), separate the specified terms from a row variable by a pipe::
134 (name :: String, age :: Number | r)
136Type Synonyms
137-------------
139For convenience, it is possible to declare a synonym for a type using the ``type`` keyword. Type synonyms can include type arguments.
141For example::
143 type Foo = { foo :: Number, bar :: Number }
145 addFoo :: Foo -> Number
146 addFoo = \o -> o.foo + o.bar
148Constrained Types
149-----------------
151Polymorphic types may be predicated on one or more ``constraints``. See the chapter on type classes for more information.
153Type Annotations
154----------------
156Most types can be inferred (not including Rank N Types and constrained types), but annotations can optionally be provided using a double-colon::
158 one = 1 :: Number