编写haskell库
首先我们准备一个很小的文件:
--file: Books.hs
module Books
(
BookInfo,
book
) where
data BookInfo = Book {
bookId :: Int,
bookName :: String,
author :: [String]
} deriving (Eq,Show)
book = Book {
bookId = 123456,
author = ["abc"],
bookName = "haskell"
}
haskell 模块
一个haskell文件可以包含一个模块定义,模块可以决定模块中的哪些名字可以被外部访问,如
module Books
(
BookInfo,
book
) where
module
是保留字,后面的Books
是模块名,魔魁啊名字不许以大写开头,并且必须与模块的文件基础名(不包含后缀的文件名)一致.模块名后用括号包围的是导出列表,where
关键字之后的内容为模块的体.
导出列表决定模块中的哪些名字对于外部模块是可见的,使得私有代码可以隐藏在模块的内部.这样能力允许模块对用户隐藏类型的细节,将一个类型变得抽象.
real world 示范了一种在类型构造器后添加
(..)
的用法,表示导出类型构造器以及它所有的值构造器.
如果省略掉模块定义中的导出列表,那么所有名字将被导出;如果不想导出模块中的任何名字,那么可以将导出列表留空,只保留一对括号.
module Books where
-- 导出所有名字
module Books () where
-- 不到处任何名字
编译 haskell 代码
编译一个haskell源码文件可以通过ghc命令来完成
$ghc -c Books.hs
-c
表示让ghc只生成目标代码,如果省略-c
则ghc会尝试生成一个完整的可执行文件,但由于没有main函数,目前无法编译完整的可执行程序.
在编译完成后,会生成两个新文件.其中Books.hi
是接口文件,ghc以及机器可读的格式,将模块中导出名字的信息保存在这个文件.而Books.o
则是目标文件,它包含了已生成的机器码.
载入模块和生成可执行文件
写一个单独的Main.hs
主程序来执行.
--file:Main.hs
module Main(main) where
import Books
main = print book
模块定义之后,import
用来导入模块,使其在Main
中可用.所有的import
指令需要在模块的首部,不能随意放置.
Main.hs
的名字和main
函数的名字是特有的,即是专为主程序设定的命名.ghc需要一个命名为Main
的模块,并且这个模块里还要一个main
函数,而main
函数在程序执行时会被调用.
ghc -o main Main.hs
-o
表示输出文件的名字.注意到此次编译没有-c
参数,ghc将尝试生成一个可执行程序,这个过程被称为链接.
一旦编译完成就可以运行编译所得内容.
$main
Book {bookId = 123456, bookName = "haskell", author = ["abc"]}
创建包
cabal 是haskell社区用来构建,安装和发布软件的一套标准工具,cabal将软件组织为包,一个包有且只能有一个库,但可以有多个可执行程序.
为包添加描述
每个Cabal包都需要一个名字,这个名字需要与cabal文件的名字相同.
-- file : bookinfo.cabal
Name: bookinfo
Version: 0.1
Synopsis: a library of bookinfo
Descreption:
A simple test of creating package
-- Description 一个字段可以有多行,只要缩进即可
Author: AgileFastx
Maintainer: somebody@realworldhaskell.org
Cabal-Version : >= 1.2
-- 指定兼容的Cabal版本
build-type: Simple
library
Exposed-Modules: Books
-- 可选字段`Other-Modules`模块支持内部功能,但对于用户不可见
Build-Depends: base >= 2.0
-- 依赖包,用逗号隔开
配置,构建和安装
除了.cabal文件,我们还需要一个setup文件,这使得Cabal可以在需要的时候自定义构建过程.最简单的示例文件如下:
-- file: Setup.hs
import Distribution.Simple
main = defaultMain
我们使用一个简单的命令告诉Cabal如何构建一个包,以及往哪里安装这个包.如果不给configure提供任何参数,Cabal会把包安装在系统包数据库里.
$runghc Setup configure
完成之后,我们来构建这个包.
$runghc Setup build
成功之后,我们就可以安装包了.我们不需要告诉Cabal装在哪,它会使用我们在第一步里提供的信息.
$runghc Setup install
调用库
ghci>import Books
ghci Books>
ghci>:module +Books
ghci Books>
ghc包管理器
ghc-pkg list
用于查看有哪些包已经被安装,如果需要卸载包则只需ghc-pkg unregister
(还需要手动删除已安装的包)
ghc-pkg list
E:\ghcup\ghc\8.6.5\lib\package.conf.d
Cabal-2.4.0.1
Win32-2.6.1.0
array-0.5.3.0
base-4.12.0.0
binary-0.8.6.0
books-0.1
bytestring-0.10.8.2
containers-0.6.0.1
deepseq-1.4.4.0
directory-1.3.3.0
filepath-1.4.2.1
(ghc-8.6.5)
ghc-boot-8.6.5
ghc-boot-th-8.6.5
ghc-compact-0.1.0.0
ghc-heap-8.6.5
ghc-prim-0.5.3
ghci-8.6.5
haskeline-0.7.4.3
hpc-0.6.0.3
integer-gmp-1.0.2.0
json1-0.1
libiserv-8.6.3
mtl-2.2.2
parsec-3.1.13.0
pretty-1.1.3.6
process-1.6.5.0
rts-1.0
stm-2.5.0.0
template-haskell-2.14.0.0
text-1.2.3.1
time-1.8.0.2
transformers-0.5.6.2
xhtml-3000.2.2.1