summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAndrei Barbu <andrei@0xab.com>2021-08-25 03:20:51 -0400
committerAndrei Barbu <andrei@0xab.com>2021-10-08 19:45:29 -0400
commita76409c758d8c7bd837dcc6c0b58f8cce656b4f1 (patch)
tree95dde306e370fe296ef84efa959828e8ecdd1267 /docs
parent55a6377a5d55d6e6e93cf3d087f1e2d17fe7d3f3 (diff)
downloadhaskell-a76409c758d8c7bd837dcc6c0b58f8cce656b4f1.tar.gz
Add defaulting plugins.
Like the built-in type defaulting rules these plugins can propose candidates to resolve ambiguous type variables. Machine learning and other large APIs like those for game engines introduce new numeric types and other complex typed APIs. The built-in defaulting mechanism isn't powerful enough to resolve ambiguous types in these cases forcing users to specify minutia that they might not even know how to do. There is an example defaulting plugin linked in the documentation. Applications include defaulting the device a computation executes on, if a gradient should be computed for a tensor, or the size of a tensor. See https://github.com/ghc-proposals/ghc-proposals/pull/396 for details.
Diffstat (limited to 'docs')
-rw-r--r--docs/users_guide/9.4.1-notes.rst5
-rw-r--r--docs/users_guide/extending_ghc.rst58
2 files changed, 63 insertions, 0 deletions
diff --git a/docs/users_guide/9.4.1-notes.rst b/docs/users_guide/9.4.1-notes.rst
index aae0c065d7..ce70b8e98d 100644
--- a/docs/users_guide/9.4.1-notes.rst
+++ b/docs/users_guide/9.4.1-notes.rst
@@ -9,6 +9,11 @@ Compiler
- New :ghc-flag:`-Wredundant-strictness-flags` that checks for strictness flags
(``!``) applied to unlifted types, which are always strict.
+- A new type of plugin: defaulting plugins. These plugins can propose
+ defaults for ambiguous variables that would otherwise cause errors
+ just like the built-in defaulting mechanism.
+
+
``base`` library
~~~~~~~~~~~~~~~~
diff --git a/docs/users_guide/extending_ghc.rst b/docs/users_guide/extending_ghc.rst
index 309fa6c912..ef9b584f04 100644
--- a/docs/users_guide/extending_ghc.rst
+++ b/docs/users_guide/extending_ghc.rst
@@ -1275,6 +1275,64 @@ The output is as follows:
| ^^^^^^^^^^^^^
+.. _defaulting-plugins:
+
+Defaulting plugins
+~~~~~~~~~~~~~~~~~~
+
+Defaulting plugins are called when ambiguous variables might otherwise cause
+errors, in the same way as the built-in defaulting mechanism.
+
+A defaulting plugin can propose potential ways to fill an ambiguous variable
+according to whatever criteria you would like. GHC will verify that those
+proposals will not lead to type errors in a context that you declare.
+
+Defaulting plugins have a single access point in the `GHC.Tc.Types` module
+
+::
+
+ -- | A collection of candidate default types for a type variable.
+ data DefaultingProposal
+ = DefaultingProposal
+ { deProposalTyVar :: TcTyVar
+ -- ^ The type variable to default.
+ , deProposalCandidates :: [Type]
+ -- ^ Candidate types to default the type variable to.
+ , deProposalCts :: [Ct]
+ -- ^ The constraints against which defaults are checked.
+ }
+
+ type DefaultingPluginResult = [DefaultingProposal]
+ type FillDefaulting = WantedConstraints -> TcPluginM DefaultingPluginResult
+
+ -- | A plugin for controlling defaulting.
+ data DefaultingPlugin = forall s. DefaultingPlugin
+ { dePluginInit :: TcPluginM s
+ -- ^ Initialize plugin, when entering type-checker.
+ , dePluginRun :: s -> FillDefaulting
+ -- ^ Default some types
+ , dePluginStop :: s -> TcPluginM ()
+ -- ^ Clean up after the plugin, when exiting the type-checker.
+ }
+
+
+The plugin gets a combination of wanted constraints which can be most easily
+broken down into simple wanted constraints with ``approximateWC``. The result of
+running the plugin should be a ``DefaultingPluginResult``, a list of types that
+should be attempted for a given type variable that is ambiguous in a given
+context. GHC will check if one of the proposals is acceptable in the given
+context and then default to it. The most robust context to provide is the list
+of all wanted constraints that mention the variable you are defaulting. If you
+leave out a constraint, the default will be accepted, and then potentially
+result in a type checker error if it is incompatible with one of the constraints
+you left out. This can be a useful way of forcing a default and reporting errors
+to the user.
+
+There is an example of defaulting lifted types in the GHC test suite. In the
+`testsuite/tests/plugins/` directory see `defaulting-plugin/` for the
+implementation, `test-defaulting-plugin.hs` for an example of when defaulting
+happens, and `test-defaulting-plugin-fail.hs` for an example of when defaults
+don't fit and aren't applied.
.. _plugin_recompilation: