restore the T1-T9 types and clarify how generic concepts work
This commit is contained in:
parent
01bc5f32d6
commit
01207b6cfd
2 changed files with 36 additions and 6 deletions
|
|
@ -116,7 +116,8 @@ type class matches
|
||||||
``array`` any array type
|
``array`` any array type
|
||||||
``set`` any set type
|
``set`` any set type
|
||||||
``seq`` any seq type
|
``seq`` any seq type
|
||||||
``any`` any type
|
``auto`` any type
|
||||||
|
``any`` distinct auto (see below)
|
||||||
================== ===================================================
|
================== ===================================================
|
||||||
|
|
||||||
Furthermore, every generic type automatically creates a type class of the same
|
Furthermore, every generic type automatically creates a type class of the same
|
||||||
|
|
@ -196,6 +197,9 @@ supply all type parameters of the generic type, because any missing ones will
|
||||||
be inferred to have the equivalent of the `any` type class and thus they will
|
be inferred to have the equivalent of the `any` type class and thus they will
|
||||||
match anything without discrimination.
|
match anything without discrimination.
|
||||||
|
|
||||||
|
To help you write more concise implicitly generic procs, the Nim's system
|
||||||
|
module includes the named types `T1` through `T9` which are bind once aliases
|
||||||
|
of the `auto` type.
|
||||||
|
|
||||||
Concepts
|
Concepts
|
||||||
--------
|
--------
|
||||||
|
|
@ -273,7 +277,7 @@ value that will be matched only as a type.
|
||||||
Please note that the ``is`` operator allows one to easily verify the precise
|
Please note that the ``is`` operator allows one to easily verify the precise
|
||||||
type signatures of the required operations, but since type inference and
|
type signatures of the required operations, but since type inference and
|
||||||
default parameters are still applied in the concept body, it's also possible
|
default parameters are still applied in the concept body, it's also possible
|
||||||
to encode usage protocols that do not reveal implementation details.
|
to describe usage protocols that do not reveal implementation details.
|
||||||
|
|
||||||
Much like generics, concepts are instantiated exactly once for each tested type
|
Much like generics, concepts are instantiated exactly once for each tested type
|
||||||
and any static code included within the body is executed only once.
|
and any static code included within the body is executed only once.
|
||||||
|
|
@ -378,8 +382,8 @@ operator and also when types dependent on them are being matched:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
type
|
type
|
||||||
MyConcept[M, N: static[int]; T] = concept x
|
MatrixReducer[M, N: static[int]; T] = concept x
|
||||||
x.foo(SquareMatrix[N, T]) is array[M, int]
|
x.reduce(SquareMatrix[N, T]) is array[M, int]
|
||||||
|
|
||||||
The Nim compiler includes a simple linear equation solver, allowing it to
|
The Nim compiler includes a simple linear equation solver, allowing it to
|
||||||
infer static params in some situations where integer arithmetic is involved.
|
infer static params in some situations where integer arithmetic is involved.
|
||||||
|
|
@ -410,7 +414,7 @@ to match several procs accepting the same wide class of types:
|
||||||
|
|
||||||
On the other hand, using ``bind once`` types allows you to test for equivalent
|
On the other hand, using ``bind once`` types allows you to test for equivalent
|
||||||
types used in multiple signatures, without actually requiring any concrete
|
types used in multiple signatures, without actually requiring any concrete
|
||||||
types, thus allowing you to encode implementation detail types:
|
types, thus allowing you to encode implementation-defined types:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
type
|
type
|
||||||
|
|
@ -425,10 +429,25 @@ types, thus allowing you to encode implementation detail types:
|
||||||
# and it must be a numeric sequence
|
# and it must be a numeric sequence
|
||||||
|
|
||||||
As seen in the previous examples, you can refer to generic concepts such as
|
As seen in the previous examples, you can refer to generic concepts such as
|
||||||
Enumerable[T] just by their short name. Much like the regular generic types,
|
`Enumerable[T]` just by their short name. Much like the regular generic types,
|
||||||
the concept will be automatically instantiated with the bind once auto type
|
the concept will be automatically instantiated with the bind once auto type
|
||||||
in the place of each missing generic param.
|
in the place of each missing generic param.
|
||||||
|
|
||||||
|
Please note that generic concepts such as `Enumerable[T]` can be matched
|
||||||
|
against concrete types such as `string`. Nim doesn't require the concept
|
||||||
|
type to have the same number of parameters as the type being matched.
|
||||||
|
In order to express such a requirement, you'll need to rely on a type
|
||||||
|
mapping operator such a `genericHead` or `stripGenericParams` within the
|
||||||
|
concept body:
|
||||||
|
|
||||||
|
.. code-block:: nim
|
||||||
|
import future, typetraits
|
||||||
|
|
||||||
|
type
|
||||||
|
Functor[A] = concept f
|
||||||
|
f.value is A
|
||||||
|
map(f, A -> T1) is genericHead(f.type)[T1]
|
||||||
|
|
||||||
|
|
||||||
Concept derived values
|
Concept derived values
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,17 @@ type
|
||||||
SomeNumber* = SomeInteger|SomeReal
|
SomeNumber* = SomeInteger|SomeReal
|
||||||
## type class matching all number types
|
## type class matching all number types
|
||||||
|
|
||||||
|
T1* = auto
|
||||||
|
T2* = auto
|
||||||
|
T3* = auto
|
||||||
|
T4* = auto
|
||||||
|
T5* = auto
|
||||||
|
T6* = auto
|
||||||
|
T7* = auto
|
||||||
|
T8* = auto
|
||||||
|
T9* = auto
|
||||||
|
## Helper types for writing implicitly generic procs
|
||||||
|
|
||||||
proc defined*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
proc defined*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
|
||||||
## Special compile-time procedure that checks whether `x` is
|
## Special compile-time procedure that checks whether `x` is
|
||||||
## defined.
|
## defined.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue