-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathREADME.pod6
135 lines (88 loc) · 3.65 KB
/
README.pod6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
=begin pod
[![Build Status](https://github.com/Kaiepi/ra-Kind/actions/workflows/test.yaml/badge.svg)](https://github.com/Kaiepi/ra-Kind/actions/workflows/test.yaml)
=head1 NAME
Kind - Typechecking based on kinds
=head1 SYNOPSIS
=begin code :lang<raku>
use Kind;
my constant Class = Kind[Metamodel::ClassHOW];
proto sub is-class(Mu --> Bool:D) {*}
multi sub is-class(Class --> True) { }
multi sub is-class(Mu --> False) { }
say Str.&is-class; # OUTPUT: True
say Blob.&is-class; # OUTPUT: False
=end code
=head1 DESCRIPTION
C<Kind> is an uninstantiable parametric type that can be used to typecheck
values based off their kind. A parameterization produces a type object that can
process the HOW of a type in a typecheck context with C<ACCEPTS> when
available, otherwise falling back to the bare typecheck.
C<Kind> is documented. You can view the documentation for it and its methods at
any time using C<WHY>.
=head1 METAMETHODS
=head2 method parameterize
=for code :lang<raku>
method ^parameterize(|args) is raw
Produces a parameterization by delegating to C<^kind> with C<args>.
=head2 method kind
=for code :lang<raku>
method ^kind(Mu $obj is raw, Mu \K, Mu:U \T = Mu) is raw
Produces a cached subset with a refinement (C<where>) built from C<K> and a
refinement (C<of>) from C<T> if present. This backs C<^parameterize> so as to
allow for a different parameterizer in a subtype. This is more or less a
wrapper for C<Metamodel::Primitives.parameterize_type>.
Some useful values with which to produce a type are:
=item a metaclass or metarole
=for code :lang<raku>
# Smartmatches any class.
Kind[Metamodel::ClassHOW]
=item a junction of metaclasses or metaroles
=for code :lang<raku>
# Smartmatches any type that supports naming, versioning, and documenting.
Kind[Metamodel::Naming & Metamodel::Versioning & Metamodel::Documenting]
=item a block
=for code :lang<raku>
# Smartmatches any parametric type.
Kind[{ use nqp; nqp::hllbool(nqp::can($_, 'parameterize')) }]
=item a metaobject
=begin code :lang<raku>
# This class' metamethods constrain their metaobject to itself or its subtypes.
class Configurable {
my constant K := Kind[$?CLASS.HOW.WHAT, $?CLASS];
my constant %configuration := hash;
method ^configure(K $obj, %config --> Map:D) {
%configuration{$obj.WHAT.WHICH} := %config.Map
}
method ^configuration(K $obj --> Map:D) {
%configuration{$obj.WHAT.WHICH} // Map.new
}
}
=end code
For more examples of parameterizations of C<Kind>, refer to
C<t/01-typecheck.t>.
=head1 SYMBOLS
=head2 &set_parameterizer
=for code :lang<raku>
our sub set_parameterizer(Mu $obj is raw, ¶meterizer = ¶meterize --> Nil)
Applies the parameterizer of C<Kind> to a metaobject, providing it with a
parameterization cache. A subtype needs to apply this at C<BEGIN>-time in order
to parameterize with the default metamethods, for instance:
=for code :lang<raku>
class Kind::Instantiable is Kind {
BEGIN Kind::set_parameterizer($?CLASS);
}
A C<¶meterizer> may be provided, in which case that will be set instead.
This should carry a compatible signature with C<¶meterize>.
For more examples of how to subclass C<Kind>, refer to C<t/02-meta.t>.
=head2 ¶meterize
=for code :lang<raku>
our sub parameterize(Mu $root is raw, Any $args) is raw
Given the C<$root> metaobject of the parameterization and its C<$args>,
produces a type object minus the caching. C<$args> is assumed to carry C<K> at
position C<0> and C<T>, if present, at position C<1>.
=head1 AUTHOR
Ben Davies (Kaiepi)
=head1 COPYRIGHT AND LICENSE
Copyright 2022 Ben Davies
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.
=end pod