scotty 系列教程之前言

scotty 系列教程是建立在读者具有一定 haskell 基础的前提上,
若没有请移步去阅读一本关于 haskell 编程的书,如:《Real World Haskell》。

scotty 系列教程将一步一步引导读者开发一个 coin 项目。涉及的内容如下:

  • 如何使用 stack 快速构建 haskell 项目
  • 第一个应用 echo
  • 访问 mysql 数据库
  • 使用 haxl 框架
  • rest ful json api
  • 使用 graphql
  • 结语

预备工作

haskell 所提供 cabal 构建工具相对来将比较复杂,所以我选择使用 stack 构建工具。

安装 stack

详细的安装请自行查看文档
我自己使用的是 gentoo,安装如下:

emerge --ask dev-haskell/stack 

mac os 安装如下:

brew install haskell-stack 

第一个项目 hello world

$ stack new helloworld
Downloading template "new-template" to create project "helloworld" in helloworld/ ...
Looking for .cabal or package.yaml files to use to init the project.
Using cabal packages:
- helloworld/helloworld.cabal

Selecting the best among 10 snapshots...

Downloaded lts-8.5 build plan.
* Matches lts-8.5

Selected resolver: lts-8.5
Initialising configuration using resolver: lts-8.5
Total number of user packages considered: 1
Writing configuration to file: helloworld/stack.yaml
All done.

我们从日志可以看到 stack 使用的最新的模版创建 helloworld 这个项目,并且下载了最新的编译解决方案 lts-8.5

编译

我们进入 helloworld 目录进行编译:

$ cd helloworld 
$ stack build 
No compiler found, expected minor version match with ghc-8.0.2 (x86_64) (based on resolver setting in /Users/lmj/repo/dispatch/helloworld/stack.yaml).
To install the correct GHC into /Users/lmj/.stack/programs/x86_64-osx/, try running "stack setup" or use the "--install-ghc" flag. To use your system GHC installation, run "stack config set system-ghc --global true", or use the "--system-ghc" flag.

报错了,从日志可以知道 stack 没有找到 ghc 编译器。
我们可以简单执行 stack setup 来安装 ghc 编译器。
我自己是使用系统的 ghc brew install ghc,所以后面的教程使用的都是系统的 ghc

加了 --system-ghc 参数重新编译

$ stack build --system-ghc
Warning: File listed in helloworld.cabal file does not exist: README.md
helloworld-0.1.0.0: configure (lib + exe)
Configuring helloworld-0.1.0.0...
helloworld-0.1.0.0: build (lib + exe)
Preprocessing library helloworld-0.1.0.0...
[1 of 1] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Lib.o )
Preprocessing executable 'helloworld-exe' for helloworld-0.1.0.0...
[1 of 1] Compiling Main             ( app/Main.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/helloworld-exe/helloworld-exe-tmp/Main.o )
Linking .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/helloworld-exe/helloworld-exe ...
Warning: File listed in helloworld.cabal file does not exist: README.md
helloworld-0.1.0.0: copy/register
Installing library in
/Users/lmj/repo/dispatch/helloworld/.stack-work/install/x86_64-osx/lts-8.5/8.0.2/lib/x86_64-osx-ghc-8.0.2/helloworld-0.1.0.0-44GC3BWnM1QFjPMM1ngxcQ
Installing executable(s) in
/Users/lmj/repo/dispatch/helloworld/.stack-work/install/x86_64-osx/lts-8.5/8.0.2/bin
Registering helloworld-0.1.0.0...

编译成功了,我们执行一下它:

$ stack exec --system-ghc helloworld-exe 
someFunc

哈哈,成功了。

Hello World!

下面我们把 someFunc 改成我们要的 Hello World!
我们看一下目录树:

$ tree 
.
├── LICENSE
├── Setup.hs
├── app
│   └── Main.hs
├── helloworld.cabal
├── src
│   └── Lib.hs
├── stack.yaml
└── test
    └── Spec.hs

3 directories, 7 files

目录树中 app/Main.hshelloworld 的入口。
src/Lib.hshelloworld 的主代码,专门给 app/Main.hs 调用的。

我们打开 src/Lib.hs:

module Lib
    ( someFunc
    ) where

someFunc :: IO ()
someFunc = putStrLn "someFunc"

putStrLn "someFunc" 就是输出的信息,我们把 someFunc 改为 Hello World! 今天的教程就完工。

改完如下:

module Lib
    ( someFunc
    ) where

someFunc :: IO ()
someFunc = putStrLn "Hello World!"

编译执行一下:

$ stack build --system-ghc
Warning: File listed in helloworld.cabal file does not exist: README.md
helloworld-0.1.0.0: unregistering (local file changes: src/Lib.hs)
helloworld-0.1.0.0: build (lib + exe)
Preprocessing library helloworld-0.1.0.0...
[1 of 1] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Lib.o )
Preprocessing executable 'helloworld-exe' for helloworld-0.1.0.0...
[1 of 1] Compiling Main             ( app/Main.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/helloworld-exe/helloworld-exe-tmp/Main.o ) [Lib changed]
Linking .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/helloworld-exe/helloworld-exe ...
Warning: File listed in helloworld.cabal file does not exist: README.md
helloworld-0.1.0.0: copy/register
Installing library in
/Users/lmj/repo/dispatch/helloworld/.stack-work/install/x86_64-osx/lts-8.5/8.0.2/lib/x86_64-osx-ghc-8.0.2/helloworld-0.1.0.0-44GC3BWnM1QFjPMM1ngxcQ
Installing executable(s) in
/Users/lmj/repo/dispatch/helloworld/.stack-work/install/x86_64-osx/lts-8.5/8.0.2/bin
Registering helloworld-0.1.0.0...

$ stack exec --system-ghc helloworld-exe
Hello World!

课后作业

src/Lib.hsapp/Main.hs 里面的 someFunc 函数名也应该做相应的改动,这些就留给读者自己完成了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,064评论 25 707
  • //Clojure入门教程: Clojure – Functional Programming for the J...
    葡萄喃喃呓语阅读 3,604评论 0 7
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,945评论 4 60
  • 走在冬雨的甬道上, 风掠过满地的沧桑。 万木调落的季节里, 就连翠竹也抵不住昨日的霜。 桂花却在寒冷中绽放, 绿萝...
    冬蝉子阅读 449评论 2 2