hakyll- A static website compiler library

Safe HaskellNone




Module providing pattern matching and capturing on Identifiers. Patterns come in two kinds:

  • Simple glob patterns, like foo/*;
  • Custom, arbitrary predicates of the type Identifier -> Bool.

They both have advantages and disadvantages. By default, globs are used, unless you construct your Pattern using the predicate function.

A very simple pattern could be, for example, foo/bar. This pattern will only match the exact foo/bar identifier.

To match more than one identifier, there are different captures that one can use:

  • *: matches at most one element of an identifier;
  • **: matches one or more elements of an identifier.

Some examples:

  • foo/* will match foo/bar and foo/foo, but not foo/bar/qux;
  • ** will match any identifier;
  • foo/** will match foo/bar and foo/bar/qux, but not bar/foo;
  • foo/*.html will match all HTML files in the foo/ directory.

The capture function allows the user to get access to the elements captured by the capture elements in the pattern.

Like an Identifier, a Pattern also has a type parameter. This is simply an extra layer of safety, and can be discarded using the castPattern function.


The pattern type

data Pattern a Source

Type that allows matching on identifiers


castPattern :: Pattern a -> Pattern bSource

Discard the phantom type parameter

Creating patterns

parseGlob :: String -> Pattern aSource

Parse a pattern from a string

predicate :: (Identifier a -> Bool) -> Pattern aSource

Create a Pattern from an arbitrary predicate


 predicate (\i -> matches "foo/*" i && not (matches "foo/bar" i))

list :: [Identifier a] -> Pattern aSource

Create a Pattern from a list of Identifiers it should match

regex :: String -> Pattern aSource

Create a Pattern from a regex


 regex "^foo/[^x]*$

inGroup :: Maybe String -> Pattern aSource

Create a Pattern which matches if the identifier is in a certain group (or in no group)

complement :: Pattern a -> Pattern aSource

Inverts a pattern, e.g.

 complement "foo/bar.html"

will match anything except "foo/bar.html"

Applying patterns

matches :: Pattern a -> Identifier a -> BoolSource

Check if an identifier matches a pattern

filterMatches :: Pattern a -> [Identifier a] -> [Identifier a]Source

Given a list of identifiers, retain only those who match the given pattern

capture :: Pattern a -> Identifier a -> Maybe [String]Source

Match a glob against a pattern, generating a list of captures

fromCapture :: Pattern a -> String -> Identifier aSource

Create an identifier from a pattern by filling in the captures with a given string


 fromCapture (parseGlob "tags/*") "foo"



fromCaptures :: Pattern a -> [String] -> Identifier aSource

Create an identifier from a pattern by filling in the captures with the given list of strings