Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create ReadTheDocs project for unordered-containers. #249

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "docs/_extensions/haddock-autolink"]
path = docs/_extensions/haddock-autolink
url = https://github.com/m-renaud/haddock-autolink
11 changes: 11 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2

sphinx:
configuration: docs/conf.py

submodules:
include:
- docs/_extensions/haddock-autolink

python:
version: 2.7
89 changes: 89 additions & 0 deletions Tutorial.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{-# OPTIONS_GHC -fno-warn-unused-imports #-}

{-|
The @unordered-containers@ package provides implementations of various
hash-based immutable data structures.

Some of the data structures provided by this package have a very large API
surface (for better or worse). The docs here focus on the most common functions
which should be more than enough to get you started. Once you know the basics,
or if you're looking for a specific function, you can head over to the
full API documentation!
-}


module Tutorial (
-- * Provided Data Structures
-- $provideddatastructures

-- * Related Packages
-- $relatedpackages

-- * Looking for more resources?
-- $moreresources

-- * Installing and using the @unordered-containers@ packages #installing#

-- ** Version Requirements
-- $versionreqs

-- ** Importing modules
-- $importingmodules

-- ** In GHCi
-- $ghci

-- * HashSet and HashMap tutorial
-- $tutorials

) where

{- $provideddatastructures
* "Data.HashSet" - unordered, non-duplicated elements
* '"Data.HashMap" - unordered map from keys to values (aka. dictionaries)
-}

{- $relatedpackages
* <https://hackage.haskell.org/packages/containers containers> - ordered containers using trees instead of hashing.
* <https://hackage.haskell.org/packages/hashable containers> - types that can be converted to a hash value.
-}

{- $moreresources
If you've worked your way through the documentation here and you're looking for
more examples or tutorials you should check out:

* <https://haskell-lang.org/library/containers haskell-lang.org's containers tutorial>, its focused on the ordered
<https://hackage.haskell.org/packages/containers containers> library but provides some useful examples.
* <http://learnyouahaskell.com/modules Learn You a Haskell "Modules" chapter>
-}

{- $versionreqs
All of the examples here should work for all recent versions of the package.
-}

{- $importingmodules

All of the modules in @unordered-containers@@ should be imported @qualified@
since they use names that conflict with the standard Prelude.

@
import qualified "Data.HashSet" as HashSet
import qualified "Data.HashMap.Strict" as HashMap
@

-}


{- $ghci
Start the GHCi
<https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop REPL> with
@ghci@, @cabal repl@, or @stack ghci@. Once the REPL is loaded, import the
modules you want using the @import@ statements above and you're good to go!
-}


{- $tutorials

See "Tutorial.HashSet" and "Tutorial.HashMap".

-}
15 changes: 15 additions & 0 deletions Tutorial/HashMap.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{-# OPTIONS_GHC -fno-warn-unused-imports #-}

{-|
Sets allow you to store *unique* elements, providing efficient insertion,
lookups, and deletions. If you are storing sets of @Int@ s consider using
'Data.IntSet' from the <https://hackage.haskell.org/packages/containers containers> package. You can find the
introductory documentation for @containers@ at
<https://haskell-containers.readthedocs.io>.

@
data HashMap k v = ...
@
-}

module Tutorial.HashMap () where
197 changes: 197 additions & 0 deletions Tutorial/HashSet.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
{-# OPTIONS_GHC -fno-warn-unused-imports #-}

{-|
Sets allow you to store *unique* elements, providing efficient insertion,
lookups, and deletions. If you are storing sets of @Int@ s consider using
'Data.IntSet' from the <https://hackage.haskell.org/packages/containers containers> package. You can find the
introductory documentation for @containers@ at
<https://haskell-containers.readthedocs.io>.

@
data 'HashSet' element = ...
@


All of these implementations are /immutable/ which means that any update
functions do not modify the set that you passed in, they creates a new set. In
order to keep the changes you need to assign it to a new variable. For example:

@
import qualified Data.HashSet as HashSet

let s1 = HashSet.'HashSet.fromList' ["a", "b"]
let s2 = HashSet.'HashSet.delete' "a" s1
print s1
> HashSet.'HashSet.fromList' ["a","b"]
print s2
> HashSet.'HashSet.fromList' ["b"]
@
Comment on lines +19 to +28
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This style seems rather unusual and also doesn't fit with the way most GHCi sessions look. The usual doctest-style seems clearer to me:

Suggested change
@
import qualified Data.HashSet as HashSet
let s1 = HashSet.'HashSet.fromList' ["a", "b"]
let s2 = HashSet.'HashSet.delete' "a" s1
print s1
> HashSet.'HashSet.fromList' ["a","b"]
print s2
> HashSet.'HashSet.fromList' ["b"]
@
@
>>> import qualified Data.HashSet as HashSet
>>> HashSet.'HashSet.fromList' ["a", "b"]
fromList ["a","b"]
>>> HashSet.'HashSet.delete' "a" s1
fromList ["b"]
@


__IMPORTANT:__ @HashSet@ relies on the @element@ type having instances of the @Eq@ and
@Hashable@ typeclasses for its internal representation. These are already
defined for builtin types, and if you are using your own data type you can
use the
<https://en.wikibooks.org/wiki/Haskell/Classes_and_types#Deriving deriving>
mechanism.


-}

module Tutorial.HashSet (
-- * Short Example
-- $shortexample

-- * Importing HashSet
-- $importing

-- * Common API Functions
-- ** Construction and Conversion

-- *** Create an empty set
-- $empty

-- *** Create a set with one element (singleton)
-- $singleton

-- *** Create a set from a list
-- $fromlist

-- * Continue reading
-- $continuereading
) where

import qualified Data.HashSet as HashSet

{- $shortexample

The following GHCi session shows some of the basic set functionality:

@
import qualified Data.HashSet as HashSet

let dataStructures = HashSet.'HashSet.fromList' [\"HashSet\", \"HashMap\", \"Graph\"]

-- Check if HashMap and Trie are in the set of data structures.
HashSet.'HashSet.member' \"HashMap\" dataStructures
> True

HashSet.'HashSet.member' "Trie" dataStructures
> False


-- Add Trie to our original set of data structures.
let moreDataStructures = HashSet.'HashSet.insert' \"Trie\" dataStructures

HashSet.'HashSet.member' \"Trie\" moreDataStructures
> True


-- Remove Graph from our original set of data structures.
let fewerDataStructures = HashSet.'HashSet.delete' \"Graph\" dataStructures

HashSet.'HashSet.toList' fewerDataStructures
> [\"HashSet\", \"HashMap\"]


-- Create a new set and combine it with our original set.
let orderedDataStructures = HashSet.'HashSet.fromList' [\"Set\", \"Map\"]

HashSet.'HashSet.union' dataStructures orderedDataStructures
> fromList [\"Map\", \"HashSet\", \"Graph\", \"HashMap\", \"Set\"]
@


__TIP__: You can use the
<https://ghc.haskell.org/trac/ghc/wiki/OverloadedLists OverloadedLists>
extension so you don't need to write `fromList [1, 2, 3]` everywhere.
Instead you can just write `[1, 2, 3]` and if the function is expecting
a set it will be converted automatically! The code here will continue
to use `fromList` for clarity though.


-}


{- $importing

When using HashSet in a Haskell source file you should always use a `qualified`
import because these modules export names that clash with the standard Prelude.
You can import the type constructor unqualified.

@
import Data.HashSet (HashSet)
import qualified Data.HashSet as HashSet
@

-}

{- $commonapifunctions


.. TIP::
All of these functions that work for `HashSet` will also work for
`IntSet`, which has the element type `a` specialized to `Int`. Anywhere
that you see `HashSet Int` you can replace it with `IntSet`. This will
speed up most operations tremendously (see `Performance`_) with the exception
of `size` which is O(1) for `HashSet` and O(n) for `IntSet`.

.. NOTE::
`fromList [some,list,elements]` is how a `HashSet` is printed.

-}

{- $empty
@
HashSet.empty :: HashSet a
HashSet.empty = ...
@

`HashSet.empty' creates a set with zero elements.

@
HashSet.empty
> fromList []
@

-}

{- $singleton
@
HashSet.singleton :: a -> HashSet a
HashSet.singleton x = ...
@

'HashSet.singleton' creates a set with a single element
`x` in it.

@
HashSet.singleton "containers"
> fromList ["containers"]

HashSet.singleton 1
> fromList [1]
@
-}

{- $fromlist
@
HashSet.fromList :: [a] -> HashSet a
HashSet.fromList xs = ...
@

'HashSet.fromList' creates a set containing the elements of the
list `xs`. Since sets don't contain duplicates, if there are repeated elements
in the list they will only appear once.

@
HashSet.fromList ["base", "containers", "QuickCheck"]
> fromList [,"containers","base","QuickCheck"]
Comment on lines +187 to +188
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HashSet.fromList ["base", "containers", "QuickCheck"]
> fromList [,"containers","base","QuickCheck"]
HashSet.fromList ["base", "containers", \"QuickCheck"]
> fromList ["containers","base",\"QuickCheck"]


HashSet.fromList [1, 1, 2, 3, 4, 4, 5, 1]
> fromList [1,2,3,4,5]
@
-}

{- $continuereading
Continue the tutorial at "Tutorial.HashMap".
-}
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS = -a -E
SPHINXBUILD = sphinx-build
SPHINXPROJ = unordered-containers
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
1 change: 1 addition & 0 deletions docs/_extensions/haddock-autolink
Submodule haddock-autolink added at 51c39a
2 changes: 2 additions & 0 deletions docs/_extensions/hs-theme.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def setup(app):
app.add_stylesheet('css/hs-theme.css')
Binary file added docs/_extensions/hs-theme.pyc
Binary file not shown.
11 changes: 11 additions & 0 deletions docs/_static/css/hs-theme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.wy-side-nav-search {
background-color: #222 !important;
}

.wy-nav-top {
background-color: #333 !important;
}

.wy-nav-top i {
color: #282 !important;
}
Binary file added docs/_static/images/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/favicon-green-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions docs/_static/images/haskell-logo-black.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions docs/_static/images/haskell-logo-green.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading