1章 WebSocketを使ったチャットアプリケーション(シンプルなウェブサーバー)
(Mac OS X El Capitanを基本に書いています)
最初のプログラムとしてブラウザを使ったチャットアプリケーションを作ってみよう。 ブラウザとサーバーはWebSocketを使って通信することにします。 WebSocketっていうのはウェブサーバー/ブラウザ間の双方向通信を行う技術です。 通信がつながると、ブラウザ起点の通信だけでなく、サーバー起点の通信も可能になります。 詳しくはWikipediaを見てね。
これは書籍「Go言語によるWebアプリケーション開発」を使って Haskellの勉強をしようというシリーズです。 Haskellは書籍「関数プログラミング実践入門 ──簡潔で、正しいコードを書くために (WEB+DB PRESS plus)」を読んで勉強中。
表記について
以降の説明では次の表記を使います。
コマンド
$ echo これはコマンド実行です
これはコマンド実行です
$
始まりの行が入力したコマンド行で、それ以外は出力された行か補足です。
出力が多い時は:
で省略します。
なおrootユーザーでのコマンドは#
始まりで表記します。
ソースコード
-- 入門プログラム main = putStrLn "Hello, World!"
使用パッケージの選定
Haskellには多くのウェブフレームワークが用意されています。
今回はウェブフレームワークのひとつYesodで使われているWAI
、WARP
、WAI WebSocketsと、WebSockets、HTTP types、あとGinger
を使うことにしました。
WAI
WAI
はHaskellのウェブサーバー/フレームワークの共通インタフェースを提供します。
CGIやWSGIみたいなものでしょうか。
Warp
Warp
はWAIを使ったHaskellのHTTPサーバーライブラリです。
RubyのWEBrickみたいなものでしょうか。
WAI WebSockets
WAI WebSockets
はWAI上でWebSocketsを使うためのライブラリです。
WebSockets
WebSockets
はHaskellでWebSocketサーバーを実装するためのライブラリです。
Ginger
Ginger
はHaskellのテンプレートエンジンです。
PythonのJinja2をHaskellで実装したもののようです。
シンプルなウェブサーバー
まずはパッケージの準備を行ってシンプルなウェブサーバーを作ってみましょう。
プロジェクト用ディレクトリ作成
プロジェクトを作りたいディレクトリに移動し、stack new
でプロジェクトディレクトリを作ります。
今回は~/proj/にchatプロジェクトを作ってそこで作業をします。
$ cd ~/proj
$ stack new chat
Downloading template "new-template" to create project "chat" in chat/ ...
The following parameters were needed by the template but not provided: author-email, author-name, authorName, category, copyright, github-username
You can provide them in /Users/big/.stack/config.yaml, like this:
templates:
params:
author-email: value
author-name: value
:
Or you can pass each one as parameters like this:
stack new chat new-template -p "author-email:value" -p "author-name:value" -p "authorName:value" -p "category:value" -p "copyright:value" -p "github-username:value"Using cabal packages:
- chat/chat.cabal
:
Writing configuration to file: chat/stack.yaml
All done.
$cd chat
この出力ではパラメータ指定がされていないと出ています。 今回はサンプルですので省略しましたが、実際のプロジェクト時には作者やメールアドレスなどを指定します。(いつか調べたい)
Cabalファイル編集
まず作られたchatディレクトリにあるchat.cabal
ファイルを編集します。
Library
セクションのbuild-depends:
に使用するパッケージを追加します。
: library hs-source-dirs: src exposed-modules: Lib build-depends: base >= 4.7 && < 5 -- ここに使用パッケージ追記 , http-types , wai , warp default-language: Haskell2010 :
ソースファイル編集
次にchat/src/Lib.hs
ファイルを編集しましょう。
とりあえずsomeFunc
関数を書き換えていきます。
今回は短いので全て引用しておきます。
参考ページ
{-# LANGUAGE OverloadedStrings #-} module Lib ( someFunc ) where import Network.HTTP.Types (status200) import Network.HTTP.Types.Header (hContentType) import Network.Wai (Application, responseLBS) import Network.Wai.Handler.Warp (run) someFunc :: IO() someFunc = do let port = 3000 putStrLn $ "Listening on port " ++ show port run port app app :: Application app req f = f $ responseLBS status200 [(hContentType, "text/plain")] "Hello world!"
1行目 {-# LANGUAGE OverloadedStrings #-}
文字列リテラルである"〇〇"の扱いを変更します。
今回使用するパッケージが[Char]
ではなく、ByteString
を要求するためです。
3〜5行目 module
外部に提供するものを書きます。
雛形ではLibモジュール
としてsomeFunc
を提供しています。
7〜10行目 import
使用するパッケージを書きます。
今回は何がどのパッケージかわかるように使う要素も(〇〇)
で指定しています。
13〜16行目 run port app
Warpを利用してポート番号とApplication
を渡してサーバーを起動しています。
18〜20行目 app :: Application
WAIのApplication
型を定義しています。
リクエストに対してレスポンスとしてstatus:200
、context-type:text/plain
と内容Hello world!
を返すように定義しています。
アプリビルド
chat
ディレクトリでstack build
してみましょう。
初回はCabalファイルに追加したパッケージのインストールが行われるため、かなり時間がかかります。
$ stack build
:
chat-0.1.0.0: build
Preprocessing library chat-0.1.0.0...
:
アプリ実行
ビルドが成功したら、実行してみましょう。
$ stack exec chat-exe
Listening on port 3000
ブラウザでhttp://localhost:3000
にアクセスすると、Hello world!
メッセージが表示されれば成功です。
パチパチパチ〜
使われている基礎構文の説明
Haskell 2010 言語報告書
ちゃんと言語報告書を読んだわけではなく、実際のコードから推測したりググって調べたものを書いています。まだHaskellに慣れていないので勘違いがあったらごめんなさい。
コメント
--
から改行まではコメントとして扱われます。
ただし、他の構文に使われる字句の一部の場合はそっちが優先されます。
例えば-->
や|--
はコメントとしては扱われないです。
なので慣習的に前後に空白を置いて書かれることが多いようです。
コメントが複数行になる場合は{-
と-}
で囲むと改行を含めてコメントとして扱われます。
この形式のコメントは入れ子にできるので、ネストコメントと呼びます。
以下がコメント例です。
-- これは1行コメント {- これは複数行コメント 改行もOK {- ネストできます -} ここもコメントです -} -- {- ここは1行コメントです this_is_NOT_comment = "コメントアウトの切り替え" -- -}
最後のコメントがネストコメントのようにも見えますが、コメントアウトのイディオムです。
ネストコメントの終了を-- -}
としておくと、開始部分を1行コメントにするかどうかで、コメントアウトの切り替えができます。
また、ネストコメントはコンパイラへのプラグマ指定としても使われます。
今回のコードでは{-# LANGUAGE OverloadedStrings #-}
が使われています。
次回予定の記事で扱いますが、ソースコードとその中のコメントからドキュメントを自動生成するhaddock
というツールもあります。
-- |
や{- |
、-- ^
や{- ^
始まりのコメントがドキュメント化されます。
識別子
- 変数識別子:小文字アルファベット始まりで、英字・数字・シングルクォートが0個以上続くもの
- 構成子識別子:大文字アルファベット始まりで、英字・数字・シングルクォートが0個以上続くもの
識別子は小文字、大文字を区別し、アンダースコア_
は小文字とみなされます。
また、_
始まりの識別子はコンパイラの未使用警告を抑制するようです。
型推論
Haskellには型推論機能があります。 わざわざ書かなくても自明なものはコンパイラが自動で推測してくれます。 ただ、自明じゃないものや人に向けたドキュメントとして型を指定することもできます。
::
で型を指定します。
someFunc :: IO()
とapp :: Application
が型指定です。
左側の小文字始まりのものが変数名(関数名)で、右側の大文字始まりのものが型になります。
IO()
の()
が何を指しているかは勉強不足です。。。
let式 / where節
let
で式中でのみ有効な一時的な定義を行うことができます。
似たような構文としてwhere
節があります。
where
は式中ではなく、宣言全体で有効な一時的な定義を行うことができるようです。
きっとmodule
のwhere
もそういうものなんでしょう。
演算子
Haskellでは演算子を自分で定義することができます。
用意されている演算子は+
,-
,*
,/
などよくあるものや、$
、++
など見かけないものがあります。
(私は普段C++
を使っています)
$
は関数適用を行います。通常は左結合の所を右結合にできます。関数の引数として別の関数の結果を使いたい場合に()
を省略できて便利です。++
はリストの結合です。文字列リテラルは文字のリストなので、++
を使って結合します。
付録A 安定した開発環境のためのベストプラクティス(を知りたい)
オリジナルと合わせてベストプラクティスと題したけど、 ベストではなく1つの方法としてお読みください。 (Mac OS X El Capitanを基本に書いています)
これは書籍「Go言語によるWebアプリケーション開発」を使って Haskellの勉強をしようというシリーズです。 Haskellは書籍「関数プログラミング実践入門 ──簡潔で、正しいコードを書くために (WEB+DB PRESS plus)」を読んで勉強中。
表記について
以降の説明では次の表記を使います。
コマンド
$ echo これはコマンド実行です
これはコマンド実行です
$
始まりの行が入力したコマンド行で、それ以外は出力された行か補足です。
出力が多い時は:
で省略します。
なおrootユーザーでのコマンドは#
始まりで表記します。
ソースコード
-- 入門プログラム main = putStrLn "Hello, World!"
Haskellのインストール
手軽に試すならHaskell Platformという、 コンパイラ、ビルドシステム、開発ツール、よく使われるパッケージをひとつにまとめたものがあります。
これでもよかったのですが、stackという開発環境管理ツールがナウいらしいです。 新しいもの好きな私はstackでインストールすることにしました。
stackはコンパイラのインストールやパッケージインストールを手助けしてくれます。 またビルドシステムとしても使えパッケージの依存関係を管理してくれるため、 時々ある依存バージョン地獄に悩まされなくなって安心できます。 おかげでshebang指定でのスクリプトとしても安心して使えるようです。(Stackを使って楽しくHaskellスクリプティング)
参考ページ
Mac OS Xへのインストール
私はAnsibleを使います。
(今回はbrew install haskell-stack
だけですが)
Githubにアップしているstack_osx.ymlをダウンロードしてインストールできます。 Ansibleが入っていれば、次のコマンドでOK!
$ ansible-playbook stack_osx.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY ***************************************************************************
TASK [homebrew] ****************************************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0$ stack --version
Version 1.0.4 x86_64
補足 Ansibleのインストール
- Xcodeインストール
$ sudo xcodebuild -license
or
$ xcode-select --install - Homebrewインストール
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- Ansibleインストール
$ brew install ansible
$ ansible --version
ansible 2.0.1.0
config file =
configured module search path = Default w/o overrides
Windows 10へのインストール
私はWindows 64-bit Installerを使いました。
ダウンロードしたインストーラーを実行!
Haskellの設定
stackを使ってHaskellコンパイラをインストールします。 必要があればHTTP_PROXY環境変数を設定しておいてください。
まずはstackが使えるか確認してみましょう。
$ stack --version
Version 1.0.4 x86_64
$ stack setup
Run from outside a project, using implicit global project config
Using latest snapshot resolver: lts-5.8
Writing implicit global project config file to: /Users/big/.stack/global-project/stack.yaml
:
Installed GHC.
:
これでGHCが使えるようになりました。
$ stack ghc -- --version
Run from outside a project, using implicit global project config
Using resolver: lts-5.8 from implicit global project's config file: /Users/big/.stack/global-project/stack.yaml
The Glorious Glasgow Haskell Compilation System, version 7.10.3
プロジェクト単位の設定
stackを使うとシステムの環境とプロジェクトの環境を分けられます。 プロジェクトごとに環境を用意することで、それぞれで同じパッケージを使用していても 別のバージョンをインストールことができます。
まずはプロジェクトを作成して、作られたディレクトリに移動しましょう。
$ stack new helloworld
Downloading template "new-template" to create project "helloworld" in helloworld/ ...
:
$ cd helloworld
$ ls
LICENSE helloworld.cabal test Setup.hs src app stack.yaml
次にプロジェクト用にセットアップを行います。 通常はグローバルプロジェクトにインストールされますが、 依存するライブラリのバージョンによってはプロジェクトローカルにインストールされます。
$ stack setup
stack will use a locally installed GHC
For more information on paths, see 'stack path' and 'stack exec env'
To use this GHC and packages outside of a project, consider using:
stack ghc, stack ghci, stack runghc, or stack exec
そしてビルド。
$ stack build
[1 of 1] Compiling Main
:
Registering helloworld-0.1.0.0...
すると実行ファイルが作られるので、次のコマンドで実行!
$ stack exec helloworld-exe
someFunc
stack test
、stack bench
、stack haddock
など他にも便利機能が用意されています。
Haskellのツール
Haskellの開発をサポートするツールがたくさん用意されています。 その中のいくつかを紹介しましょう。
stack install パッケージインストール
stack install
はgo get
やpip
のようなパッケージインストールができます。
使い方
$ stack install ghc-mod stylish-haskell
:
Copied executables to /Users/big/.local/bin:
- ghc-mod
- ghc-modi
- stylish-haskell
WARNING: Installation path /Users/big/.local/bin not found on the PATH environment variable
パッケージが多いと、とっても時間がかかるので注意。
最後に書いてあるように、~/.local/bin
をPATH環境変数に登録することでインストールしたツールをstack経由でなく直接実行できるようになります。
ついでにstack ghc
やstack ghci
をaliasでghc
、ghci
としとくと便利です。
stylish-haskell ソースコード整形ツール
stylish-haskellはgo fmt
やclang-format
のようなソースコードを整形してくれます。
stackからインストールできます。
使い方
HLint ソースコード検査ツール
HLintはgo vet
やlint
のようなソースコードを検査してくれます。
stackからインストールできます。
$ stack install hlint
使い方
$ stack exec hlint app/Main.hs
No hints
Emacs
各種エディタには開発を補助する拡張機能が用意されています。 ここではEamcsの拡張機能を少しご紹介しましょう。
- haskell-mode メジャーモード
- ghc-mod エディタサポート (stack ideやhdevtoolsもあるみたい?)
ghc-mod
は1つのプログラムで、エディタと通信して使用します。
使うためにはghc-mod
をインストールしておく必要があります。
これもstack
からインストールできます。
$ stack install ghc-mod :
Copied executables to /Users/big/.local/bin:
- ghc-mod
- ghc-modi
WARNING: Installation path /Users/big/.local/bin not found on the PATH environment variable
ghc-mod
を直接使えるように、まだPATH
環境変数に登録していなければ最後に出力されたパスを~/.bash_profile
に登録します。
ではEmacsの設定をしていきます。まずMELPAを使えるように~/.emacs.d/init.el
に次のコードを書いておきましょう。
(require 'package) (add-to-list 'package-archives '("melpa" . "https://stable.melpa.org/packages/")) (package-initialize)
Emacsを起動して、M-x package-list-package
でパッケージ一覧を表示します。
下記をそれぞれ探してi
(インストールマーク)。マークをつけたらx
でインストール。
- ghc
- haskell-mode
~/.emacs.d/init.el
に下記のHaskell用の設定を追加したら準備完了!
(autoload 'ghc-init "ghc" nil t) (autoload 'ghc-debug "ghc" nil t) (add-hook 'haskell-mode-hook (lambda () (ghc-init)))
お好みでHaskell > Customize
を設定したり、init.elに追記して使いやすくしましょう。
私はhaskell-stylish-on-save
を有効にしてソースコード保存時に整形しています。
2016年1月 読書感想文 Go言語によるWebアプリケーション開発
「新春座談会 このコンピュータ書がすごい! 2016年版 —2015年に出たコンピュータ書ならこれを読め!—
↑これを今年初めてライブストリーミング配信で見て、いっぱい本が出てるなーと、いっぱい紹介できてすげーなーと。
そこで今年は毎月1冊新作技術書を読んで勉強しようと思いました。1冊のピックアップは毎月15日頃Amazon PCサイトの詳細検索を使って発売月を指定して検索して、その中で1番興味を持ったものを買います。
1月は「Go言語によるWebアプリケーション開発」洋書タイトル「Go Programming Blueprints」
- 作者: Mat Ryer,鵜飼文敏,牧野聡
- 出版社/メーカー: オライリージャパン
- 発売日: 2016/01/22
- メディア: 大型本
- この商品を含むブログ (2件) を見る
この本はだいぶ面白かった。買ってよかった。
私のGolangレベルは新しい言語をGoogleが出したんだなー、型指定がC言語と違って後ろなんだなー、並行処理が楽に書けるんだなー、程度の知識です。
C++はプログラム作る程度には使えるので説明とコードを見れば何をしているのかなんとなくわかりました。
Go言語はシンプルな構文で読みやすいですね。
この本には簡単なものですが、チャットアプリ、Web APIの使用と作成、コマンドラインツール、NoSQL、といった実際のプロダクトを作って学ぶ形式でした。
言語の勉強だと意味のないサンプルコードが多いですが、実際にアプリを作りながら学べるから面白い。
また、アプリを作るだけじゃなくて、TDDで作っていくというプログラミングの作成環境としてのGoについても書いてありいいなと思いました。普段はVisual Studioで開発してて、TDDはやりたいなーと思ってるけどなかなかできないのでいい刺激にもなりました。
同じ頃 Haskell を勉強し始めたから、この本に沿って Haskell の勉強にも使ってみようかと計画中。GoとHaskellどっちが今後自分の道具となるだろうか。
今選べるプログラミング言語は
・単純なツールなら:Windowsバッチ、Ant
・ちょっと複雑なら:Ant、C#
・製品レベルなら:C++、C#
ここにGoやHaskellが入ればもっと楽にプログラムが作れるんじゃないかなーと。
MacBook Air 13インチを買った
新しいMacBook Airが出てすぐに買った。
iPadの母艦であり開発機にしようと思う。
初Macでまだまだ慣れないけどちょっとずつ使って覚えていこう。
もう少しでMountain Lionが出るのでそれまでは試運転。
とりあえず今インストールしたもの。
KeyRemap4MacBook
http://pqrs.org/macosx/keyremap4macbook/
これを使ってJIS配列のキーボードをUS配列にした。
それだけじゃなく、英数とかなキーを別のキーにしたりといろいろ書き換えた。
まだ空きキーがあるので今後必要になったら追加していこうと思う。
SourceTree
http://itunes.apple.com/jp/app/sourcetree-git-hg/id411678673?mt=12
個人でMercurialを使っててGUIで操作できるクライアントを調べたらこれが見つかった。
いつかGitも使うかも知らんので両方対応してるのはよさそう。
まずはKeyRemap4MacBookの設定ファイルを管理してみた。
iPadに入れたアプリ
iPadを手に入れて2週間。週末にしか長時間使ってないけど、現在インストールしたアプリを記録しとこう。
電子書籍関連
とりあえずストアアプリをたくさんインストールしておいた。
今度陳列をみてリストラしていくつもり。
iBooks
http://itunes.apple.com/jp/app/ibooks/id364709193
現在はこれで自炊PDFを読んでる。もっとメモがとりやすいものにしたいが、有料アプリになってくるので熟考中。
雑誌ONLINE
http://itunes.apple.com/jp/app/za-zhionrain+books/id324946616
名前からすると雑誌がメイン?
BookWalker
http://itunes.apple.com/jp/app/book-walker/id404123731
なんだろう。
常用アプリ
よく使うであろうアプリたち。
SHOT NOTE
http://itunes.apple.com/jp/app/shot-note/id411332997
iPhoneアプリしかなかったが、ノート買ってしまったので入れてる。勉強したノートをショットしていきたい。
3D視力回復
http://itunes.apple.com/jp/app/3d-shi-li-hui-fu/id453629018
ずっとモニタを見つめて、ピント調節が固まってしまったときに使用してみようと思って購入。が、見た目がしょぼかった。
これは有料アプリ。目的はそこそこ達成できるし、85円だけどなんか失敗感を味わった。
このおかげで有料アプリはしっかり調査してから買おうと決めました。
GoodNotes
http://itunes.apple.com/jp/app/goodnotes-wu-liao-ban-shou/id483679173
ノートアプリ。手書きも拡大画面で入力できて細かい字も書けるのでいいね。
無料版をインストールしたけど、有料版にバージョンアップしてもいいかもしれない。
無料版の2ファイル限定が解除されたらメモができるPDFリーダーとしても活用するかも。
PDF上に手書きできるし、マーカーもあるし、ノートページを挿入することも出来る。
PDFリーダー候補。
UYH
http://itunes.apple.com/jp/app/shou-shukitsuru/id317514393
あとでやろうと思いついたことをリスト形式で保存してる。
チェックリストとして使えて、なにより文字が綺麗に見える。
手書き文字がきたない俺でもなんかイイ!ってなった。スタイリッシュって大事だな。
AppBank
http://itunes.apple.com/jp/app/appbank-for-ipad/id364223227
いろんなアプリのレポートがあってアプリ選びの参考にさせてもらってます。
クラウド系
クラウドを専用アプリとして使えるようにしたものたち。
SugarSync
http://itunes.apple.com/jp/app/sugarsync/id288491637
Evernote,DropBox,SugarSyncの3つどれを使おうか検討したとき、無料の容量が一番大きかったSugarSyncになった。
同期機能は使ってなくて、ただのネットワーク上のドライブとして使用中。
ネットワーク上のドライブとしてなら後述のNドライブのほうが容量多くていいと思い出した。
他アプリ連携を考えたらEvernoteやDropBoxの方が便利だとも思い出した。
SugarSyncとのお別れも近いかも。
Nドライブ
http://itunes.apple.com/jp/app/naver-ndoraibu-for-ipad/id413617492
ネットワーク上のドライブとして使用するなら30GBの容量が無料で使えるNドライブがいい。
と最近知った。ただアプリでダウンロードしたものはOpenInが使えず、Nドライブ内でしか開くことが出来ない。残念。
ブラウザからダウンロードすればOpenIn使えるだろうか?と思ってるけどまだ試せていない。
RTM
http://itunes.apple.com/jp/app/remember-the-milk/id293561396
Remember The Milkというタスク管理アプリ。
前から気になっててようやく登録してみる気になった。
まだ登録してないけど。常時接続じゃないから、オフラインでどれくらい使えるかが気になるところ。
なんとなく入れてみた
暇なときに見たり、いつか必要になるかと思って入れてるものたち。
e国宝
http://itunes.apple.com/jp/app/e-guo-bao/id413457009
国立博物館所蔵の物が画像と解説をみれてなんかいい。
オフラインで使えなかったのが残念。
路線図
http://itunes.apple.com/jp/app/marugoto-lu-xian-tu/id417547679
ちょっと旅に出たくなったときに眺めて行き先をきめるとか出来そう。
OneNote
http://itunes.apple.com/jp/app/microsoft-onenote-for-ipad/id478105721
画像つきの文章が書ける。
日常の何気ない日記につかえるかもとか思った。まぁ日記書いてないけど。
SketchBookX
http://itunes.apple.com/jp/app/sketchbook-mobilex/id327376639
すごいお絵かきアプリ。すごすぎて何が出来るかわからず放置。
いつか使うときが来るかもしれない。
iPadファーストインプレッション
一日iPad触ってみた。まだ全く使いこなせていないが、使いこなせたら便利そうだと思った。
とりあえずキーボードが打ち辛いけど、音声入力が意外と精度が高くて便利に使える。まあ家で居る時位しか使えないけど。
この日記も音声入力を中心で書いてみた。普段喋らないから滑舌を良くする練習にもなっていいねw
まずは電子書籍を閲覧するアプリを決めたい。
pdfにメモを書き込めるのが良いな。手書きができると便利。
小さいサイズの本だったら横に並べて見開きで見たい。ただ小さい本だったらSonyのReaderのほうが見やすいかも。
あとブラウザーで戻るをジェスチャーでできるやつはあるんかな?ページを戻る操作がめんどくさい。
明日は指紋防止用の保護フィルムを探してこよう。いちにち触ってたら指紋だらけになった…