Add higher-order types (Kinds) - #351
Conversation
There was a problem hiding this comment.
馃挕 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0993ab58ea
鈩癸笍 About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 馃憤.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| attr_reader :type | ||
|
|
||
| def ===(object) | ||
| Literal.subtype?(object, @type) |
There was a problem hiding this comment.
Accept wrapped container types in kind matching
KindType#=== currently relies on Literal.subtype?(object, @type), but module-based subtyping only succeeds for a small subset of literal wrapper types (ConstraintType, IntersectionType, UnionType, NeverType). As a result, _Kind(Array) rejects _Array(Integer) (and similarly for other wrappers like _Hash), even though those types are semantically constrained to arrays. This makes higher-order constraints unexpectedly fail for common generic type arguments.
Useful? React with 馃憤聽/ 馃憥.
There was a problem hiding this comment.
No it doesn't. Look at the implementation of Literal.subtype?
Added a
_Kindgeneric to create higher-order types (kinds). This type constructor takes a type and return the type of its type. In other words, it will match the type itself or any subtype of that type.This is useful in situations where you want to take a type as an argument and you want to constrain what kinds of types are allowed.
_Kindworks for complex types tooIf you want to compose one kind into another, you can lift it with
type.I am using this to create operation classes where parameters must be only serialisable types. It means we can know at boot time rather than runtime that all types on the operations can only match objects that can be serialized / deserialized.