Skip to content

Latest commit

 

History

History
61 lines (44 loc) · 2.58 KB

README.md

File metadata and controls

61 lines (44 loc) · 2.58 KB

Regex.Spec

Generates type specifications for Regular Expressions at compile time allowing Dialyzer to detect type errors.

Build Status Hex.pm

This library is a work in progress that was inspired by Stephanie Weirich's talk Dependent Types in Haskell at Strange Loop 2017. The design is evolving based on the constraints imposed by Elixir:

  1. we cannot specify a list of n elements, so we need to return a tuple
  2. we use String.t() | nil to represent a maybe type based on a (...)? pattern
  3. we generate a map of results with optional and required keys for named captures
  4. can we pass in a list of parse functions that can be applied to the matches and modify the return type e.g. from String.t() -> integer()

This library generates the common Regex functions for your regular expression with a type spec. Create a module for your type and use:

defmodule MyApp do

  defmodule MMYYDDDD do
    use Regex.Spec, regex: ~r/(\d{2})\-(\d{2})\-(\d{4})/
  end

  IO.inspect(MMYYDDDD.matches?("2020-12-31")) # false
  IO.inspect(MMYYDDDD.run("12-31-2020")) # ["12-31-2020", "12", "31", "2020"]
  IO.inspect(MMYYDDDD.runt("12-31-2020")) # {"12-31-2020", "12", "31", "2020"}

end

The specification for run/3 is a list of Strings, and we cannot specify a dependent type such as a list of length 4. Therefore we implement the normal run function and also runt which can be read as run typed or run tuple which returns a typed tuple.

Installation

This library is incomplete, but you can append to your mix.exs deps:

    {:regex_spec, "~> 0.21"}

Design

This library uses leex and yecc to compile your regular expression into a tree of capture groups and then into a Dialyzer tuple type specification.

The docs can be found at https://hexdocs.pm/regex_spec.