[HS] 使用 Hackage: tree-diff

1. 准备环境

首先下载Haskell Platform,它包含了GHC,Cabal,还有其他的一些工具。
Mac OS X下载完后是一个pkg文件,例如,Haskell Platform 8.2.2 Full 64bit-signed.pkg
双击安装即可。

2. 新建工程

使用cabal命令行工具,初始化工程,

$ mkdir my-tree-diff    # 新建工程目录
$ cd my-tree-diff       # 进入目录
$ cabal init            # 初始化项目

然后就有一些提示,以填写与工程相关的配置选项,
例如,package-name,package version,license,author name,maintainer email,等等。
一般使用默认值即可,唯一需要手动输入选项的是,

> What does the package build:
   1) Library
   2) Executable
Your choice? 2          # 这里我们选2,工程会生成一个可执行文件

填写完成后,cabal会自动生成一些文件,

my-tree-diff
├── ChangeLog.md
├── LICENSE
├── Main.hs
├── Setup.hs
└── my-tree-diff.cabal

3. 编译 & 运行

直接在工程目录下,执行cabal run,就会自动编译并执行,

$ cabal run

Resolving dependencies...
Configuring my-tree-diff-0.1.0.0...
Preprocessing executable 'my-tree-diff' for my-tree-diff-0.1.0.0..
Building executable 'my-tree-diff' for my-tree-diff-0.1.0.0..
[1 of 1] Compiling Main             ( Main.hs, dist/build/my-tree-diff/my-tree-diff-tmp/Main.o )
Linking dist/build/my-tree-diff/my-tree-diff ...
Running my-tree-diff...
Hello, Haskell!

其中,Hello, Haskell!Main.hs中输入的结果,

module Main where

main :: IO ()
main = putStrLn "Hello, Haskell!"

注:
如果只编译,可以执行cabal build

$ cabal build

Preprocessing executable 'my-tree-diff' for my-tree-diff-0.1.0.0..
Building executable 'my-tree-diff' for my-tree-diff-0.1.0.0..

4. 工程依赖

使用cabal创建的工程,依赖的Hackage包,需要在my-tree-diff.cabal文件中配置,

在该文件中,我们可以找到,build-depends: base >=4.10 && <4.11
它表示默认依赖了base包。

我们修改build-depends字段的值,为之添加以下包,
他们是本例展示tree-diff使用方法所必须的,

build-depends:
    base >=4.10 && <4.11,
    tree-diff,
    containers,
    pretty

其中basetree-diffcontainersprettyHackage中的包名,
各依赖通过逗号来隔开,也可以省略版本号。

5. 修改Main.hs文件

module Main where

import Data.Tree         -- 隶属于containers包
import Text.PrettyPrint  -- 隶属于pretty包

import Data.TreeDiff     -- 隶属于tree-diff包

tree1 :: Tree Char
tree1 = Node 'a' [
            return 'b', 
            Node 'c' [
                return 'd', 
                return 'e'
            ], 
            return 'f'
        ]

tree2 :: Tree Char
tree2 = Node 'a' [
            return 'b', 
            Node 'c' [
                return 'd', 
                return 'e'
            ], 
            return 'g' 
        ]

main :: IO ()
main = putStrLn $ render $ prettyEditExpr $ ediff tree1 tree2

其中,ediffprettyEditExprrender的类型如下,

-- tree-diff包,Data.TreeDiff.Class模块中
ediff :: ToExpr a => a -> a -> Edit EditExpr

-- tree包,Data.TreeDiff.Pretty模块中
prettyEditExpr :: Edit EditExpr -> Doc

-- pretty包,Text.PrettyPrint模块中
render :: Doc -> String

此外,return的类型如下,

-- containers包,Data.Tree模块中
return :: a -> Tree a

6. 执行结果

$ cabal run 

Preprocessing executable 'my-tree-diff' for my-tree-diff-0.1.0.0..
Building executable 'my-tree-diff' for my-tree-diff-0.1.0.0..
[1 of 1] Compiling Main             ( Main.hs, dist/build/my-tree-diff/my-tree-diff-tmp/Main.o )
Linking dist/build/my-tree-diff/my-tree-diff ...
Running my-tree-diff...
Node
  'a'
  [Node 'b' [],
   Node 'c' [Node 'd' [], Node 'e' []],
   Node -'f' +'g' []]

参考

Haskell: Downloads
The Haskell Cabal
Hackage: tree-diff - Data.TreeDiff.Class - ediff
Hackage: tree-diff - Data.TreeDiff.Pretty - prettyEditExpr
Hackage: pretty - Text.PrettyPrint - render
Hackage: containers - Data.Tree - return

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容