Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any standard module / namespace naming convention in haskell?

Tags:

haskell

I'm basically from python world and have been playing around with haskell for few days.

As an python user, namespaces of libraries from hackage / stackage was the most confusing.

For example, in python, we will import Scotty module like import scotty, while haskell will do import Web.Scotty.

Haskellers who upload their libraries on stackage or hackage seems to prefer putting their libraries under namespaces of a category (e.g. Web, Language, ...).

Leaving whether it's a good approach or not in perspective view of dependency control outside of discussion, is there any de-facto convention on this categorization?

Is there any community-consented guide like "Put these kind of libraries under Network category and put those kind of libraries under Web category or Data category." ?

like image 915
June Avatar asked Nov 27 '15 02:11

June


People also ask

How to define a module in Haskell?

Haskell's module design is relatively conservative: the name-space of modules is completely flat, and modules are in no way "first-class." Module names are alphanumeric and must begin with an uppercase letter. There is no formal connection between a Haskell module and the file system that would (typically) support it.

What are the naming conventions and how are namespaces established?

The convention for creating a namespace identifier is to always use lowercase letters. The source files inside of a namespace must conform to a standard directory naming and structure.

How do I load a module in Haskell?

The syntax for importing modules in a Haskell script is import <module name>. This must be done before defining any functions, so imports are usually done at the top of the file. One script can, of course, import several modules. Just put each import statement into a separate line.


1 Answers

The package name, the package tags, and the module names are all independent things.

The package name is an arbitrary identifier (as long as it doesn't clash with anyone else). Its conventional to make it all lower case with hyphens between words. If several packages are part of a family then the format is e.g. "llvm-base" with the family name first. According to the Cabal manual package names can have letters, numbers and hyphens but not spaces. I don't know about any other punctuation, but I'd avoid it even if Cabal lets it through. Also thanks to the different rules about capital letters in pathnames between Windows and Linux there can be confusion, so its best to stick to lower case.

The tags are used to help sites like Hackage organise the list of packages into useful groups, and have no other significance.

Within a package will be one or more modules. These are what the client source code will import. Modules exist in a hierarchical name space. So for example the "parsec" package includes a module "Text.Parsec.Combinator". You can think of the dots as akin to Linux "/" in a path name (and in fact the source will be in a file at "src/Text/Parsec/Combinator.hs").

There are a few top-level conventional module names, such as "Control", "Data", "Text" and "System", which you can use according to the primary job of the module. Its good style to use them, but not obligatory. The appearance of the package name in the module name (e.g "Parsec") is only there to avoid name clashes; there is no formal relationship between the package name and the modules it holds.

It is quite possible to have a package with modules in different top-level hierarchies. For instance you might have a package containing "System.Foo" and "Data.Foo".

Broadly speaking "Control" is used for monads and related stuff, especially monadic and arrow combinators. But since a monad is also a data type you shouldn't feel the need to put a monadic type in a separate module just to get it into "Control".

"Data" is a catch-all. If in doubt, put it in Data.

"System" is used for operating system facilities, especially stuff that might not be portable.

"Text" is used for manipulating text, parsing, printing and so on. Anything with a lot of string manipulation probably belongs here.

"Graphics": obviously.

Its optional to have a module name at one level and then other modules below it. So "Text.Parsec" is a module, and so is "Text.Parsec.Combinators", but the designer of Parsec did not need to include "Text.Parsec". When this is done it usually means that the top level module (in this case "Text.Parsec") exports a common subset of its child modules, so in many cases the client code just needs to import "Text.Parsec" rather than the whole family.

like image 137
Paul Johnson Avatar answered Oct 20 '22 05:10

Paul Johnson