読者です 読者をやめる 読者になる 読者になる

ナカザンドットネット

Android Developer's memo

はじめてのはすける1

Haskell

スタートHaskell

7/24(日)に開催された「第0回 スタートHaskell」に参加してきました。
なんか周りの人達が「HaskellかわいいよHaskell」みたいな話をしてたり、Real World Haskell読んだりしてて面白そうだなあと思ってたのとか、Scalaを勉強してたときにイミフだったλあたりを知るために関数型言語学びたいなあ、とか思ってたあたりで初心者向けイベントが行われるということでIYH!しちゃいました。
どんなことをやったイベントだったかは公式のGoogleグループでも見ていただくとして。
// 全体的に内容が雑多すぎてよく分からんイベントになってたなーという印象

プログラミングHaskell

プログラミングHaskell

「スタートHaskell」自体は↑の本を12月までかけて読み進めていくらしいです。
が、僕は新潟に引き篭っているので参加し続けるのは無理かな・・・ということで、とりあえずその場でポチッと

f:id:Nkzn:20110731205758j:image:w360


買っちゃったものは仕方ないんで、独学で読み進めちゃおうかなーってな感じで。

ぷろぐはすける P1〜7

主に「関数」とはなんぞや?とか「関数プログラミング」とは?とか、Haskellの歴史とは?みたいな話。

P7までに出てきたコードは↓の2つ。

--倍にする関数
double x = x + x

↑は物凄く「数学」の公式っぽいんですよね。はすけらーの人達が言う「Haskellは数学」の意味が早くも見え始めた感じです。

--空リストに関数sumを適用したものはゼロ
sum [] = 0

--関数sumは、リストxsの先頭から取り出したxについて、xと「リストxsに関数sumを適用したもの」を加算する
sum (x:xs) = x + sum xs

これも数学のどっかで見たことある気がする書き方。
全然根拠はないけど、TeXと相性良さそうだなあ、とか思った。TeXHaskellのポーティングとかできるのかしら。(意味あるのかアレだけど)

つまづいたところ

sum関数が↑のままじゃコンパイルできなかった。エラーメッセージはこんなん。

$ ghc sum.hs

sum.hs:2:17:
    Ambiguous occurrence `sum'
    It could refer to either `Main.sum', defined at sum.hs:1:0
                          or `Prelude.sum', imported from Prelude

Main.sumが今回作ったsum関数っぽい。で、Prelude.sumというのが別にあるらしい。
どっちのsumのこと言ってんのか分かんねーぞクソが!とコンパイラ様は仰っているわけですね。

そもそもPreludeってなんぞ。

Haskellのインタープリタ実行環境GHCiを起動すると、「Prelude>」というプロンプトが現れます。
ぐぐってみると、

Prelude は、Haskell のコードを書けば自動的に import される。前奏曲と覚えておけばカッコイイか。
Haskell の Prelude 散策 (1) - リスト操作 : 要素の重ね合わせ (folds) | すぐに忘れる脳みそのためのメモ

ふむふむ、どうやらPreludeとはHaskellにおけるデフォルトライブラリ(モジュール?)のことらしい。
自動で読み込まれる点でちょっと違うかも知れないが、C言語におけるstdio.hやstdlib.hあたりと似た位置づけだと理解しておくとしよう。*1

自作sumを動かすには

単純に関数名をsum以外の何かにしてあげればOK。

sumx [] = 0
sumx (x:xs) = x + sumx xs

これを実行すると

$ ghci sum.hs
GHCi, version 6.10.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( sum.hs, interpreted )
Ok, modules loaded: Main.
*Main> sumx [1,2,3]
6

こんな感じでちゃんと実行できるようになります。*2


今日はこんなもんで。

余談

せめてEmacsHaskell開けるようにしようと思って、MacPortsEmacshaskell-modeを探してみました。

sudo port search haskell-mode

あったー\(>ヮ<)/

sudo port install haskell-mode.el

ターミナル「Xcodeのバージョン低すぎてビルドとかできそうにないんですけどー?」(=公=)

Xcode3.x系の最新版を入れる(2009年の夏頃から更新してなかった)

sudo port install haskell-mode.el

ターミナル「MacPortsのバージョン古すぎるんだよselfupdateかけろやコラ」

sudo port -d selfupdate

portのアップデートだけで済むかと思いきや、portで管理してるパッケージ全部のアップデートしてるんじゃないのレベルで色々ビルド

ようやくおわったー

sudo port install haskell-mode.el

haskell-modeのインストールだけで済むかと思いきやportで管理してるEmacs関連パッケージ全部の(ry

~/.emacs.elに↓のコード足してdone.

;;; haskell
(load "haskell-site-file")
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
(add-hook 'haskell-mode-hook 'font-lock-mode)
(add-hook 'haskell-mode-hook 'imenu-add-menubar-index)
(setq haskell-program-name "/opt/local/bin/ghci")

無駄に長い道のりだった。。。

*1:たぶんHaskell/関数型言語が持つ各種の概念は他言語と比べないで理解したほうが素直に覚えられそうな気がするけど、まあモジュールの概念は他言語とそんなに変わらないと思うので勘弁。

*2:ちなみに、このときにもPreludeはロードされているので、sum [1,2,3]でも同様の結果は得られちゃったりします。