auto-split: Case splitting plugin

[ bsd3, development, library ] [ Propose Tags ] [ Report a vulnerability ]

A GHC plugin that performs automatic case splitting


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 0.1.0.0
Change log CHANGELOG.md
Dependencies base (<5), ghc (>=9.6 && <9.13), ghc-exactprint (<1.13), ghc-paths (<0.2), syb (<0.8), transformers (<0.7) [details]
Tested with ghc ==9.12.1, ghc ==9.10.1, ghc ==9.8.2, ghc ==9.6.6
License BSD-3-Clause
Author Aaron Allen
Maintainer aaronallen8455@gmail.com
Category Development
Source repo head: git clone https://github.com/aaronallen8455/auto-split
Uploaded by aaronallen8455 at 2025-02-03T04:52:06Z
Distributions
Downloads 8 total (8 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
All reported builds failed as of 2025-02-03 [all 1 reports]

Readme for auto-split-0.1.0.0

[back to package description]

auto-split

A GHC plugin that performs automatic case splitting.

Usage

This plugin is intended to be used with GHCi or adjacent utilities such as ghcid and ghciwatch as a developement tool, not as a package dependency. Here is an example command for starting a REPL for a stack project with the auto-split plugin enabled:

stack repl my-project --package auto-split --ghci-options='-fplugin AutoSplit'

likewise for a cabal project:

cabal repl my-project --build-depends auto-split --repl-options='-fplugin AutoSplit'

With the plugin enabled, use SPLIT in a pattern match for a case statement or function declaration. Compiling the module will then result in that pattern match being expanded to cover all missing cases.

For example, compiling this module

module Foo where

foo :: Maybe Bool -> String
foo x = case x of
  SPLIT -> undefined

results in the module file being updated to

module Foo where

foo :: Maybe Bool -> String
foo x = case x of
  Just _ -> undefined
  Nothing -> undefined

if the module is then changed to

module Foo where

foo :: Maybe Bool -> String
foo x = case x of
  Just SPLIT -> "foo"
  Nothing -> "bar"

compiling will result in

module Foo where

foo :: Maybe Bool -> String
foo x = case x of
  Just True -> "foo"
  Just False -> "foo"
  Nothing -> "bar"

The SPLIT pattern can be used in this way anywhere a pattern match group occurs: case statements, lamba case, or function declarations.

If case splitting results in constructors or patterns that are not in scope, they will be qualified with NOT_IN_SCOPE.

Compilation will abort when case splitting occurs since the module file has been updated. This is done by having GHC emit a custom error. This error does not indicate that something went wrong.

Known limitations

  • A module must pass the type checker for splitting to occur, unless the -fdefer-type-errors GHC flag is used.
  • Using SPLIT in pattern match will insert patterns for all missing cases in the group. It doesn't restrict to the position where SPLIT is used.
  • Doesn't work well with the view patterns syntax extension
  • Doesn't apply to code inside CPP conditional blocks
  • The plugin only supports certain GHC versions with the intent of supporting the four latest release series, i.e. 9.6.* thru 9.12.*. The cabal file indicates the currently supported versions.