我基本上来自蟒蛇世界,并且已经和haskell玩了几天。
作为python用户,来自hackage / stackage的库的命名空间是最令人困惑的。
例如,在python中,我们将导出Scotty
模块,如import scotty
,而haskell将执行import Web.Scotty
。
在堆栈或hackage上上传库的Haskellers似乎更喜欢将他们的库放在类别的名称空间下(例如Web
,Language
,...)。
在讨论之外的依赖控制的透视图中,不管它是否是一个好的方法,这种分类是否有任何事实上的约定?
是否有任何社区同意的指南,例如"将这些类型的库放在Network
类别下,并将这些类型放在Web
类别或Data
类别下。&# 34; ?
答案 0 :(得分:5)
包名称,包标签和模块名称都是独立的东西。
包名称是一个任意标识符(只要它不与其他任何人冲突)。它的常规使它全部小写,单词之间用连字符。如果几个包是一个家庭的一部分,那么格式是例如首先是姓氏的“llvm-base”。根据Cabal手册包名称可以包含字母,数字和连字符,但不能包含空格。我不知道任何其他标点,但即使Cabal让它通过,我也会避免它。另外由于Windows和Linux之间路径名中大写字母的不同规则可能存在混淆,因此最好坚持使用小写。
标签用于帮助像Hackage这样的网站将包列表组织成有用的组,并且没有其他意义。
在一个包中将是一个或多个模块。这些是客户端源代码将导入的内容。模块存在于分层名称空间中。因此,例如“parsec”包包括模块“Text.Parsec.Combinator”。您可以将点视为类似于路径名中的Linux“/”(实际上源将位于“src / Text / Parsec / Combinator.hs”中的文件中)。
有一些顶级常规模块名称,例如“Control”,“Data”,“Text”和“System”,您可以根据模块的主要工作使用它们。它使用它们的好风格,但不是强制性的。模块名称中的包名称的外观(例如“Parsec”)仅用于避免名称冲突;软件包名称与其拥有的模块之间没有正式关系。
很有可能在不同的顶级层次结构中包含模块。例如,您可能有一个包含“System.Foo”和“Data.Foo”的包。
一般来说,“控制”用于单子和相关的东西,尤其是monadic和箭头组合器。但是由于monad也是一种数据类型,你不应该觉得需要将monadic类型放在一个单独的模块中,只是为了让它进入“Control”。
“数据”是一个包罗万象的。如有疑问,请将其放入数据中。
“System”用于操作系统设施,尤其是可能无法移植的东西。
“Text”用于处理文本,解析,打印等。任何带有大量字符串操作的东西都可能属于这里。
“图形”:显然。
它是可选的,在一个级别具有模块名称,然后在其下面具有其他模块。因此“Text.Parsec”是一个模块,“Text.Parsec.Combinators”也是如此,但Parsec的设计者不需要包含“Text.Parsec”。完成此操作后,通常意味着顶级模块(在本例中为“Text.Parsec”)导出其子模块的公共子集,因此在许多情况下客户端代码只需要导入“Text.Parsec”而不是整个家庭。