Haskell!?
もちろん聞いたことはあるけど触ったことないです。。。
よし触ってみよう!
今回はHaskellで簡単なWebアプリを作ってみようと思います。
ほんと触りのところまでで恐縮ですが。。。
環境は下記です。
Haskell
Stack
Ubuntu 14.04
vagrant 2.0.0
Stackのインストール
Stackとは
StackはHaskellプロジェクトを開発するためのクロスプラットフォームプログラムです。
以下のような機能があります。
・隔離された場所にGHCを自動的にインストールする。
・プロジェクトに必要なパッケージをインストールする。
・プロジェクトを構築する。
・プロジェクトのテスト。
・プロジェクトのベンチマーク。
ほほう
まぁ入れてみよう。
curlかwgetどちらか好きな方で
$ curl -sSL https://get.haskellstack.org/ | sh
or
$ wget -qO- https://get.haskellstack.org/ | sh
その後
プロジェクト作成
$ stack new haskell_web_app(任意のプロジェクト名)
haskell_web_appというディレクトリが作られます。
中見てみましょう。
$ cd haskell_web_app
$ ls
このようなファイル構成ができあがってますね。
├── LICENSE
├── Setup.hs
├── app
│ └── Main.hs
├── haskell_web_app.cabal
├── src
│ └── Lib.hs
├── stack.yaml
└── test
└── Spec.hs
ビルドしてみましょう。
$ stack build
実行!
実行はstack exec <プロジェクト名>-exe
$ stack exec haskell_web_app-exe
someFunc
おお
sumeFuncとでました。
これはapp/Main.hsのものが表示されていますね。
module Main where
import Lib
main :: IO ()
main = someFunc
app/Main.hsのmainという関数が実行されていますね。
someFuncという関数を呼び出しているようです。
someFunc関数はインポートしているLibパッケージのものです。
src/Lib.hsをみてみましょう。
module Lib
( someFunc
) where
someFunc :: IO ()
someFunc = putStrLn "someFunc"
someFuncいましたね。
こいつが表示されていました。
waiをimport
さて、今回の目的はwebアプリを作ることなので、
waiというものをインポートしてみましょう。
えーっとなになに、package.yamlに追加したいモジュールを記載するとビルド時に<プロジェクト名>.cabalにコンバートされ、インストールしてくれると。。。
よし、ではpackage.yamlに追加しよう。
dependencies:
- base >= 4.7 && < 5
- wai
waiを追加しました。
ビルドしてみましょう。
$ stack build
'parse': (<unknown>): control characters are not allowed at line 0
おや、、、何か使い方違うのかな。。。
テストしてみたところ、改行一行だけいれてビルドしても同じエラーでした。
なんだ!?文字コードか!?vagrant上での開発が影響しているのか。。。
ということで、Windowsとの共有フォルダを変更することにしました。
config.vm.synced_folder "./app", "/home/vagrant/haskell/haskell_web_app/app"
config.vm.synced_folder "./src", "/home/vagrant/haskell/haskell_web_app/src"
config.vm.synced_folder "./test", "/home/vagrant/haskell/haskell_web_app/test
今回はhaskellという名前で共有フォルダを作り、まるっと共有していたのですが、app,src,test以下だけを共有することにして、package.yamlはubuntu側でvimで編集してみました。
するとうまくいきました!!
文字コードっぽいですね。。。
あ、共有フォルダを変更した際はvagrant reloadを忘れずに。
Main.hs編集
さぁ、やっとwaiをインポートできたのでMain.hsを編集していきましょう。
wai: Web Application Interface.
waiのサイトに簡単なサンプルがあるのでいれてみましょう。
ふむふむ、warpとhttp-typeというパッケージもインストールする必要があるみたいですね。
package.yamlに追加。
dependencies:
- base >= 4.7 && < 5
- wai
- warp
- http-types
ホスト名とポートだけ修正しています。
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
app :: Application
app _ respond = do
putStrLn "I've done some IO here"
respond $ responseLBS
status200
[("Content-Type", "text/plain")]
"Hello, Web!"
main :: IO ()
main = do
putStrLn $ "http://192.168.33.10:3000/"
run 3000 app
実行!
ビルドして実行してみましょう。
$ stack excec haskell_web_app-exe
http://192.168.33.10:3000/
よし、Webからhttp://192.168.33.10:3000にアクセスしてみましょう。
ブラウザにHello, Web!と出ていたら成功です。
まとめ
今回は初めてHaskellに触ってみましたが、正直コードの中身については完全には理解できておりません。
Haskellを理解するにはまだ時間が必要そうです。。。
今後も勉強していきたいと思います。
以上、ありがとうございました。