Improve documentation, reduce duplication and add examples to haddock
- 主要语言
- Haskell
- 星标
- 400
- 派生
- 145
- PR 合并指标
- 30 天内没有已合并 PR
描述
I've successfully setup `doctests` for a few of my projects, here is one such example:
https://github.com/lehins/massiv/blob/3d5c093abfa04119c9bc100758cae6de374e6f07/massiv/massiv.cabal#L104-L116
Adding examples to haddock that are actually checked during CI brings enormous value not only to the end user, but to overall quality of a project.
I suggest adding small examples to each of the functions in:
* `Data.Vector`
* `Data.Vector.Primtive`
* `Data.Vector.Storable`
* `Data.Vector.Unboxed`
* `Data.Vector.Mutable`
* `Data.Vector.Primtive.Mutable`
* `Data.Vector.Storable.Mutable`
* `Data.Vector.Unboxed.Mutable`
Granted, there will be repetition, but it doesn't come without great value. Each example would act as a small unit test for each particular vector type, in fact, all of them would execute different code paths.
At first sight this might look like an approach that increases haddock duplication, but there is a second part to it. Documentation itself for each of the functions in above modules should be minimal, with a link to it's counterpart in the `Generic` modules. As to functions in `Data.Vector.Generic` and `Data.Vector.Generic.Mutable`, their documentation should be expanded describing all of the quirks. `unliftio` is a great example of where this approach works extremely well, eg. [createDirectory](https://www.stackage.org/haddock/nightly-2020-02-02/unliftio-0.2.12/UnliftIO-Directory.html#v:createDirectory). They can't contain doctests without choosing one of the four representations, so it might not be as beneficial to put examples there, but potentially linking back to monomorphic variants instead could solve that problem.
Here is a concrete example:
```haskell
module Data.Vector.Primitive where
...
-- | /O(1)/ First element. See `G.head` for more info.
--
-- ====__Examples__
--
-- >>> import Data.Vector.Primitive as VP
-- >>> VP.head $ VP.fromList [1,2,3,4::Int]
-- 1
--
head :: Prim a => Vector a -> a
{-# INLINE head #-}
head = G.head
```
```haskell
module Data.VEctor.Generic where
...
-- | /O(1)/ Extract the first element of a vector. This is a partial function and will
-- throw an error if the supplied vector is empty. Consider using a safer alternative
-- @(v `!?` 0)@. A monadic variant `headM` is also available.
--
-- ====__Examples__
--
-- For usage examples see:
--
-- * @Data.Vector.`Data.Vector.head`@
-- * @Data.Vector.Primitive.`Data.Vector.Primitive.head`@
-- * @Data.Vector.Storable.`Data.Vector.Storable.head`@
-- * @Data.Vector.Unboxed.`Data.Vector.Unboxed.head`@
--
head :: Vector v a => v a -> a
{-# INLINE_FUSED head #-}
head v = v ! 0
```
This whole suggestion results in two nicely documented functions with interlinking between each other:

and clicking on the link we get to version of `head` for `Primitive` vector:

贡献指南
这个仓库没有索引到贡献指南
评估
这个 Issue 还没有评估数据。