A search tool for Haskell functions, types, classes, and what-not, with an awesome database. It aims to know everything it's expected to know, including things like
- when was the function introduced
- which module the function is in
- the type
- the source (from Haskell Report, or a naive implementation)
- the optimised source used by GHC (with comments if needed)
- other ways to implement the function
- asymptotic complexity
This isn't much for now, but here's also what is planned to add:
- fixities
- alternate names for operators (like "bind" for
>>=
) RULES
and fusion information- descriptions
- inputs on which the function isn't total, and what error messages it can give
- unexistent functions (which aren't in any package and so everyone rewrites them all the time)
- advanced search, supporting queries like "all functions added in GHC 7.8"
The knowledge base is organised as several files in the db
folder.
They are written in YAML.
Sample function description (I added blank lines to make reading easier):
# Beware of names like "null" or "[]", which will be interpreted wrongly
# by YAML. If unsure, better wrap it in quotes (single or double).
# Operators should *not* be wrapped in parens.
- name: elem
# This field will have several entries if the function was moved between
# modules or packages in some version. For instance, if a function was
# always in Data.List, but also got reexported in Prelude in base-4.7:
#
# - modules: [Data.List]
# versions: []
# - modules: [Prelude]
# versions: [4.7]
location:
# This field can be omitted for "base".
- package: base
modules: [Prelude, Data.List]
# This field can be omitted if the function "always was there".
# See below to find out how to describe version ranges.
versions: []
# Pretty much any implementation which can be encountered by the user
# should be here. This includes implementations from Haskell Report,
# standard teaching implementations, and specific implementations from
# GHC, JHC, etc. Don't be afraid of including compiler-specific magic,
# as people who need it *need* it, and people who don't need it can just
# not look at it if they don't want to.
implementations:
# The list of standard names is given below.
- name: report
# Better always wrap this one in quotes.
type: "(Eq a) => a -> [a] -> Bool"
# Asymptotic complexity. There's no fixed syntax, just make it
# understandable for the person who is going to read it. Also,
# it's an optional field.
complexity: O(n)
# Fixity (as it's written in source). This is optional too.
fixity: infix 4
# Can be multiline. Also, try to break long lines.
code: |
elem x = any (== x)
Sample class method description:
- name: max
location:
- modules: [Prelude, Data.Ord]
implementations:
- name: report
type: "(Ord a) => a -> a -> a"
class: Ord
code: |
max x y
| x <= y = y
| otherwise = x
Sample class description:
- name: class Ord
location:
- modules: [Prelude, Data.Ord]
implementations:
- name: report
# This is what's actually written between "class" and "where".
type: "Eq a => Ord a"
methods:
- name: compare
# Types have to be written without this class's constraint,
# like they appear in actual code.
type: "a -> a -> Ordering"
# Several names can be specified. Try to preserve the grouping
# which the source had originally.
- name: ['<', '<=', '>=', '>']
type: "a -> a -> Bool"
- name: [max, min]
type: "a -> a -> a"
Sample datatype description:
- name: data Maybe
location:
- modules: [Prelude, Data.Maybe]
implementations:
- name: report
# This is what is between "data" and "=" in "data Maybe a = ...".
type: "Maybe a"
deriving: [Eq, Ord, Read, Show]
constructors:
- name: Nothing
# Means "Just a".
- name: Just
params: [a]
- name: Nothing
location:
- modules: [Prelude, Data.Maybe]
implementations:
- name: report
type: "Maybe a"
# Specifies which datatype the constructor belongs to.
datatype: Maybe
- name: Just
location:
- modules: [Prelude, Data.Maybe]
implementations:
- name: report
type: "a -> Maybe a"
datatype: Maybe
Names for implementations are currently:
- "report" for Haskell Report implementations.
- "naive" for naive/teaching implementations.
- "ghc" for GHC additions, things added to
base
which aren't in the Report, etc. - Anything else is valid for inclusion as well: for instance, one of the
implementations of
reverse
is called "with accumulator".
Version ranges should be written as follows:
[]
means that something was always available.[X]
means that something was available starting from version X.[A, B, C, D]
means that something was available from A until B, then from C until D (i.e. in D it was no longer available).["0", A, B]
means that something was removed in A and introduced again in B. So, "0" is a shortcut for "1st version".
Note that e.g. 4.7
is going to be interpreted as a number, so you should either write 4.7.0.0
or "4.7"
.
The latter variant is better.