A GHC plugin to remove support for recursion.
General recursion can be the cause of a lot of problems. This removes recursion from GHC, allowing you to guarantee you’re using other mechanisms, like recursion schemes.
NoRecursion plugin
A GHC plugin to remove support for recursion
General recursion can be the cause of a lot of problems. This removes recursion from GHC, allowing you to guarantee you’re using other mechanisms, like recursion schemes.
usage
Add no-recursion
to your build dependencies.
Add -fplugin NoRecursion
to your GHC options. This can be done per-module with
{-# OPTIONS_GHC -fplugin NoRecursion #-}
Now, any recursion in that module will result in a compilation failure.
NB: This won’t prevent you from using recursive functions imported from other modules, but inlined definitions from other modules will be checked.
allowing some recursion
NoRecursion supports two source annotations: "Recursion"
and "NoRecursion"
.
You can re-enable recursion for individual top-level names like
recDef :: a -> b
recDef = myRecDef
{-# ANN recDef "Recursion" #-}
Or you can re-enable recursion for an entire module with
{-# ANN module "Recursion" #-}
And then you can re-disable recursion for individual names with
nonRecDef :: a -> a
nonRecDef = id
{-# ANN nonRecDef "NoRecursion" #-}
If both '"Recursion"' and "NoRecursion"
annotations exist on the same name (or module), it’s treated as NoRecursion
.
NB: If multiple names are mutually recursive, then they must all have recursion enabled to avoid being flagged by the plugin.
ANN
has some caveats:
ANN
isn’t allowed by Safe Haskell, so any module that uses it will be inferred asUnsafe
.If you enable the
OverloadedStrings
language extension, you will have to specify the type in the annotation, like{-# ANN module "Recursion" :: String #-}
For more about how to use annotations, see the GHC User’s Guide.
licensing
This package is licensed under The GNU AGPL 3.0 or later. If you need a license for usage that isn’t covered under the AGPL, please contact Greg Pfeil.
When last checked, all transitive dependencies were licensed under The 3-Clause BSD License. However, you should review the license report for more details.
comparisons
Other projects similar to this one, and how they differ.
WartRemover
WartRemover is a Scala linting tool. A Recursion
wart was added in 2017, and I’ve been meaning to write this plugin ever since. It only took seven years to find a few hours to make it happen …