Signed-off-by: Jim Pryor <profjim@jimpryor.net>
type Weight = Integer
type Person = (Name, Address) -- supposing types Name and Address to be declared elsewhere
type Weight = Integer
type Person = (Name, Address) -- supposing types Name and Address to be declared elsewhere
- then you can use a value of type `Integer` wherever a `Weight` is expected, and vice versa. `newtype` and `data` on the other hand, create genuinely new types. `newtype` is basically just an efficient version of `data` that you can use in special circumstances. `newtype` must always take one type argument and have one value constructor. For example:
+ then you can use a value of type `Integer` wherever a `Weight` is expected, and vice versa. <!-- `type` is allowed to be parameterized -->
+
+ `newtype` and `data` on the other hand, create genuinely new types. `newtype` is basically just an efficient version of `data` that you can use in special circumstances. `newtype` must always take one type argument and have one value constructor. For example:
newtype PersonalData a = PD a
You could also say:
newtype PersonalData a = PD a
You could also say:
- data PersonalData a = PD a
+ data PersonalData2 a = PD2 a
- And `data` also allows multiple type arguments, and multiple variants and value constructors.
+ And `data` also allows multiple type arguments, and multiple variants and value constructors. <!-- Subtle difference: whereas `PersonalData a` is isomorphic to `a`, `PersonalData2 a` has an additional value, namely `PD2 _|_`. In a strict language, this is an additional type an expression can have, but it would not be a value. -->
OCaml just uses the one keyword `type` for all of these purposes:
OCaml just uses the one keyword `type` for all of these purposes:
* When a type only has a single variant, as with PersonalData, Haskell programmers will often use the same name for both the type and the value constructor, like this:
* When a type only has a single variant, as with PersonalData, Haskell programmers will often use the same name for both the type and the value constructor, like this:
- data PersonalData a = PersonalData a
+ data PersonalData3 a = PersonalData3 a
The interpreter can always tell from the context when you're using the type name and when you're using the value constructor.
The interpreter can always tell from the context when you're using the type name and when you're using the value constructor.