October 10, 2006

今日のHaskell - 関数を定義してみる

Haskellで簡単なサンプルプログラムを書こうとしたら、思いのほか苦戦した。
で、こんなん書けた。

add.hs

main = print a
        where a = add 2 3

add x y = x + y

1行目は、print関数を使って変数「a」を出力する処理。
2行目の「where」のところに変数「a」の定義が書いてある。「add 2 3」は関数呼び出し。
4行目に「add」関数の定義がある。「x」と「y」を引数に取り、それらを足したものを返す、という処理が書かれている。
これを実行すると、以下が出力される。

% runghc add.hs
5

すごい。二つの数字を足し合わせることに成功した。

とまあ、「add」関数を定義してみたわけですが、一行目の「main = …」というところも実は関数定義なんですよね。
「main」という変数に「print a」という処理を結び付けてるんです。
実行時に「main」に結び付けられた処理が呼び出されるんだと思います。

ちなみに、Haskell界隈では「変数を値に束縛する」とかなんとか言ったりするみたいです。
上の例だと「変数mainを値print aに束縛する」ってな感じかな?
あと、「where」の行では、変数「a」を「add 2 3」に束縛してますね。
「add 2 3をaに束縛する」ではなくて、「aをadd 2 3に束縛する」ですよ。
関数変数に束縛するんじゃなくて、変数関数に束縛するんです。

「束縛」というのは、「代入」とかそんな甘っちょろいものじゃないです。
一度変数に値を束縛すると、もうその変数に違う値を結びつけることはできないんですよ。
ここがCとかJavaとかの言語と決定的に違うところですね。
で、これがいわゆる「参照透明」ということらしいです。
参照先が常に同じ値であることが保証されるということです。
(ていうか、Haskellにおいては、変数の定義も関数の定義も同じようなもんだから、たとえばaという変数に値を結びつけるというのは、aという関数を定義しているともとらえられるわけで、だとすると、a = hogeみたいなのを二回書くのは同じ名前の関数を二つ定義してることになってしまうからダメじゃん、ということなんじゃないかなぁ。)

そして、参照透明であることにより遅延評価が可能になります。
参照先が常に同じ値であることが保証されるということは、いつ評価しても良いということになります。
必要な時に値を評価すれば良いんですね。まさに遅延評価。
そうすると、「不要な処理は実行されないし、同じ処理は二度走らない」ってな感じになるんですよ。

うん。多分こんな感じだと思います。

どうやらHaskellというプログラミング言語は、ごく一般的なプログラミング言語みたいに、処理を上から順番に書いていく感じじゃないんだよね。
僕の頭の中には、「プログラミングは上から順番に実行されるもの」っていうのが常識としてインプットされているんだけど、Haskellはその常識からかなり外れているみたいなんですよ。
そもそも「何かを順番に実行していく」ということができないらしい。
いや、それは嘘。「何かを順番に実行していく」ことはできるんだけど、ちょっと特殊なやりかたになってる。
Haskellでは、モナドという仕組みを使ってそれを実現するらしい。

モナド - Wikipedia

プログラミング言語、特に(純粋)関数型言語において、参照透過性を保ちながら状態や副作用などを扱うための枠組みの1つ。

「状態」「副作用」…。
うーん、なんだか眠くなってきた。

October 5, 2006

今日のHaskell

僕が感じたHaskellのおもしろい部分について、書けるときに書こうと思う。

とりあえず最初は「Hello World」から。

コンパイルする為のコマンドは「ghc」。
こんな感じ。

$ ghc hello.hs

Windows環境であれば、コンパイルすると「*.exe」ファイルができる。
Linux環境とかだと、例えば「hello.hs」というファイルから「hello」という実行ファイルを作る場合には以下のようにしてコマンドを実行する。

$ ghc hello.hs -o hello

うれしいことに、対話的にプログラミングする為の環境も用意されていて、「ghci」というコマンドで起動できる。

コマンドを実行すると、こんなのが出てくる。

$ ghci
   ___         ___ _
  / _ \\ /\\  /\\/ __(_)
 / /_\\// /_/ / /  | |      GHC Interactive, version 6.5, for Haskell 98.
/ /_\\\\/ __  / /___| |      http://www.haskell.org/ghc/
\\____/\\/ /_/\\____/|_|      Type :? for help.

Loading package base … linking … done.
Prelude> 

試しに以下を入力。

Prelude> putStrLn “Hello, World!”

すると、、、
出た!

Hello, World!

「putStrLn」という文字列になんだか独特な匂いを感じるのは僕だけでしょうか。
ま、そんなことはどうでもいい。

「runghc」というコマンドを使って、ファイルを直接実行することもできる。

$ cat hello.hs
main = putStrLn "Hello, World!"
$ runghc hello.hs

$ Hello, World!

出た!

はい、
ここまでは実に簡単ですね。

October 3, 2006

Haskellに触れる

以下がHaskellの公式サイト。
Haskell - HaskellWiki

Haskellにはいくつかの処理系があるみたいだけど、GHCが最もポピュラーらしい。
詳しくは以下を参照のこと。
Haskell - Wikipedia

GHCは以下からダウンロードできる。
The Glasgow Haskell Compiler
しかしMac OSX向けのコンパイラはなさげ。
どうしたらよいのやら。
ソースからコンパイルとかめんどくさそうだし、コンパイルするのにGHCのバイナリが必要らしい。
卵が先か鶏が先かみたいな。

なんとかしてMacで動かせないものか。
とりあえず検索。
haskell mac - Google 検索
——
検索結果↓
IBM 境界を越える: Haskell を使った関数型プログラミング - Japan
なんか面白そうなので、今度読もう。
CMS researcher - Intel MacでHaskellプログラミング
おお、ここの情報が役に立ちそうだ。
こっからダウンロードできるみたい。
X86OSXGhc - GHC - Trac

This page is meant to document the current state of GHC on Apple Mac OS X on Intel x86 hardware.

今ダウンロード中。

眠いので明日インストール。

追記:
インストールに若干手間取った。
とりあえずダウンロードして、

% ./configure
% sudo make install
% ghci

とやってみたが、だめっぽい。
こんなん出た。

dyld: Library not loaded: /usr/local/lib/libreadline.5.1.dylib
  Referenced from: /usr/local/lib/ghc-6.5/ghc-6.5
  Reason: image not found
Trace/BPT trap

「libreadline」というのがいるらしい。
そういえば上のX86OSXGhcのページにそんなようなのがあった。
とりあえずそれっぽいの(http://k9.dv8.org/~atomb/readline.tar.bz2)をダウンロードして「/usr/local/lib」に放り込む。
そしてコマンド実行。

% ghci

今度はこんなん出た。

dyld: Library not loaded: GMP.framework/Versions/A/GMP
  Referenced from: /usr/local/lib/ghc-6.5/ghc-6.5
  Reason: image not found
Trace/BPT trap

なんですか「GMP.framework」って。
「GMP.framework」で検索すると有益な情報が。
yonekawaのはてなダイアリー - [haskell]ふつけるふつける

configure make installインストール後、アーカイブに入ってるGMP.Frameworkを/Library/Frameworksにコピーしておしまい。

そういうことですか。
というわけで、「GMP.Framework」を「/Library/Frameworks」にコピーしてコマンド実行。

% ghci

すると、

   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.5, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Prelude> 

出た。

ていうかdanさんも同じこと書いてる。
404 Blog Not Found:haskell - GHC on Intel Mac

April 5, 2006

Haskell と SQL

Haskell って SQL に似てるな、と思った。
Haskell ではこんなプログラムが書けるらしい。(プログラム工学VI 講義資料(2001-10-30)より)

sumSquares m n
  = sqM + sqN
    where
    sqM = m * m
    sqN = n * n

「where」が SQL っぽい。
でも逆だな。
SQL が Haskell 等の関数型言語に似てるんだな。

About Haskellより。

他のよくしられた関数型言語に近い言語として、 標準的なデータベースクエリー言語である SQLがあります。 SQLのクエリーは投射、選択、結合などを含めた式になります。 クエリーには どの関係が計算されるかが記述され、どのように計算するかは記述されません。

とのこと。

それはそうと、僕は SQL がどうしても好きになれない。
関数型言語を習得すると SQL にも馴染みやすくなるかなぁ。

April 4, 2006

「計算機プログラムの構造と解釈」と「入門Haskell―はじめて学ぶ関数型言語」

計算機プログラムの構造と解釈
計算機プログラムの構造と解釈 ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン

おすすめ平均
stars原著の対訳本としてなら
stars洋書で読みましょう
stars日本語酷すぎ...
starsschemeをするには
stars原書を読もう!

Amazonで詳しく見る by G-Tools

買おうか迷ってます。

ちなみに、これはショッピングカートに入れました。

入門Haskell―はじめて学ぶ関数型言語 入門Haskell―はじめて学ぶ関数型言語
向井 淳

毎日コミュニケーションズ 2006-03
売り上げランキング :

Amazonで詳しく見る by G-Tools

こういう本(仕事に直結しないけどもプログラマとしてはどうにも興味をそそられるはずな本)を手にすると、「俺ってプログラマーだなぁ」って思う。

いや、甘いな。
本当のプログラマーってのはこういう本を普通に面白がって読むものなのだ。きっとそうに違いない。
僕の場合は、ちょっとビビってる時点でダメ。