Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

aelve/harold

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Harold

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"

Database syntax

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.

About

information about Haskell functions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published