git.iko.soy/rowtype-yoga/purescript-native
on e24efbc help sign in
159 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 ``Foo``s are constructed.
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::
84 forall r. { foo :: Number, bar :: Number | r } -> Number
86Here, the type variable ``r`` has kind ``# *`` - it represents a `row` of `types`. It can be instantiated with any row of named types.
88In other words, ``addProps`` accepts any record which has properties ``Foo`` and ``Bar``, and *any other record properties*.
90Therefore, the following application compiles::
92 addProps { foo: 1, bar: 2, baz: 3 }
94even though the type of ``addProps`` does not mention the property ``baz``. However, the following does not compile::
96 addProps { foo: 1 }
98since the `bar` property is missing.
100Rank N Types
101------------
103It 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.
105In most cases, a type annotation is necessary when using this feature.
107As an example, we can pass a polymorphic function as an argument to another function::
109 poly :: (forall a. a -> a) -> Boolean
110 poly f = (f 0 < 1) == f true
112Notice that the polymorphic function's type argument is instantiated to both `Number` and `Boolean`.
114An argument to ``poly`` must indeed be polymorphic. For example, the following fails::
116 test = poly (\n -> n + 1)
118since the skolemized type variable ``a`` does not unify with ``Number``.
120Rows
121----
123A row of types represents an unordered collection of named types without duplicates.
125Rows 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.
127To denote a closed row, separate the fields with commas, with each label separated from its type with a double colon::
129 (name :: String, age :: Number)
131It may be necessary, depending on the context, to surround a row in parentheses.
133To 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::
135 (name :: String, age :: Number | r)
137Type Synonyms
138-------------
140For convenience, it is possible to declare a synonym for a type using the ``type`` keyword. Type synonyms can include type arguments.
142For example::
144 type Foo = { foo :: Number, bar Number }
146 addFoo :: Foo -> Number
147 addFoo = \o -> o.foo + o.bar
149Constrained Types
150-----------------
152Polymorphic types may be predicated on one or more ``constraints``. See the chapter on type classes for more information.
154Type Annotations
155----------------
157Most types can be inferred (not including Rank N Types and constrained types), but annotations can optionally be provided using a double-colon::
159 one = 1 :: Number