《Real World Haskell》笔记(5):模块与库编写

2019-02-08  本文已影响0人  Mexplochin
编写Json库
--file SimpleJson.hs
--以SimpleJson为例 模块整体定义如下
module SimpleJson
  (
    JValue(..)-- JValue 后的 (..) 符号表示导出 JValue 类型以及它的值构造器
    , getString
    , getInt
    , getDouble
    , getBool
    , getObject
    , getArray
    , isNull
  ) where -- where 关键字后的内容为模块的体
--模块可以只导出类型的类构造器,而不导出这个类型的值构造器,
--它允许模块对用户隐藏类型的细节,将一个类型变得抽象。
--如果用户看不见类型的值构造器,就不能使用值构造器显式创建这种类型的值,
--也不能对值进行模式匹配,只能通过相应的 API 来创建这种类型的值。

data JValue = JString String
  | JNumber Double
  | JBool  Bool
  | JNull
  | JObject [(String,JValue)]
  | JArray [JValue]
  deriving (Eq,Ord,Show)

getString::JValue->Maybe String
getString (JString s) = Just s
getString _           = Nothing

getInt (JNumber n) = Just (truncate n)
getInt _           = Nothing

getDouble (JNumber n) = Just n
getDouble _           = Nothing

getBool (JBool b) = Just b
getBool _         = Nothing

getObject (JObject o) = Just o
getObject _           = Nothing

getArray (JArray a) = Just a
getArray _          = Nothing

isNull::JValue->Bool
isNull v            = v == JNull
--file PutJson.hs
module PutJson where

import Data.List (intercalate)
import SimpleJson

renderJValue::JValue->String
renderJValue (JString s)=show s
renderJValue (JNumber n)=show n
renderJValue (JBool True)="true"
renderJValue (JBool False)="false"
renderJValue JNull="null"
renderJValue (JObject o)="{"++pairs o++"}"
  where pairs []=""
        pairs ps=intercalate "," (map renderPair ps)
        renderPair (k,v)=show k ++ ":"++renderJValue v
renderJValue (JArray a)="["++values a++"]"
  where values []=""
        values vs=intercalate "," (map renderJValue vs)

putJValue::JValue->IO ()
putJValue v=putStrLn (renderJValue v)
Haskell模块
编译SimpleJson模块代码

使用命令ghc -c SimpleJson.hs对SimpleJson模块文件进行编译,如果省略 -c 选项,那么 ghc 就会由于试图生成完整的可执行文件而失败,因为目前的 SimpleJson.hs 没有定义 main 函数,而 ghc 在执行独立程序时会调用 main 函数。
编译完成后,生成两个新文件:

载入模块和生成可执行文件

对于已编译的SimpleJson模块库,编写执行文件的程序,如下

--file Main.hs
module Main(main) where
import SimpleJson--所有 import 指令出现在模块的开头,位于其他模块代码之前
main = print (JObject [("foo", JNumber 1), ("bar", JBool False)])

要创建可执行文件, ghc 需要一个命名为 Main 的模块,并且这个模块里面还要有一个 main 函数,main 函数在程序执行时会被调用。
使用命令ghc -o simple Main.hs对Main模块文件进行编译,由于此时ghc没有使用 -c 选项,因此会尝试生成可执行程序,这个过程被称为链接;-o 选项用于指定可执行程序的名字,在 Windows 平台下,会生成一个 .exe 后缀的文件;只要提供Main.hs,ghc 可以在一条命令中自动找到所需的文件,同时进行编译和链接,然后产生可执行文件。

Haskell开发美观打印库
--file Prettify.hs
import SimpleJson

data Doc = ToBeDefined
  deriving (Show)

string::String->Doc
string str=undefined
-- ... ...

......

Cabal包管理
--file Setup.hs
#!/usr/bin/env runhaskell
import Distribution.Simple
main = defaultMain
上一篇 下一篇

猜你喜欢

热点阅读