トップ > 技術メモ (ソフトウェア開発) >

はすけるで遊ぶ

(2005.7.18 新規作成, 2009.1 更新。)

関数型プログラミングのための言語 Haskell について。

メモ

らむだ ruby -> haskell
(2008.7.19) Rubyist九州ミーティングで、Rubyプログラマ向けにHaskellを紹介しました。
Haskell vs Ruby
HaskellとRubyとで、プログラムの書き方がどのように変わるのか。
Haskell の基本型
組み込み型についてのメモ。
リストの操作
組み込みのリスト操作関数。
HaskellでFizzBuzz問題
小さな問題をHaskellで。
HaskellのファイルIO
ファイルから読み込んだりエラー処理について。
Haskellでデータベース操作
RDBMSにSQLを投げる。Haskell cabalパッケージの扱い。
Haskell での多態 (多相)
C++のテンプレートに近いHaskellの多態。Java/C++の抽象クラスのようなアドホック多相。

次のメモはC++メインですが、前半でHaskellのMaybeモナドを解説しています。

関数型プログラミング

(2008.11.7 この節を追加。)

例えばC言語でもオブジェクト指向プログラミングができます(gtk+など)が、プログラミング言語の支援があったほうが自然にプログラミングできます。

Haskell, あるいはほかの関数型プログラミング言語 (O'Caml, Concurrent Clean, Erlang など)は、関数型プログラミングを支援します。

関数型言語は、おおむね、

というような特徴があります。

変数とオブジェクトの書き換えをおこなわないことで、平行処理が容易にできる可能性があります (concurrent computing)。

Haskellは、上の特徴に加えて、式が遅延評価(lazy evaluation)されます。例えば、リストで最初の5要素しか必要でなければ、6番目以降の要素はそもそも計算されません。

リンク

準備

(2008.11.8 この節を更新。)

Haskellでプログラムを作るには、コンパイラかインタプリタを用意します。次のようなものがあります。

The Glasgow Haskell Compiler (GHC)
コンパイラ(インタプリタも付属)で、もっともメジャー。
Hugs98
Haskellインタプリタ。Fedora 9 Linuxにはパッケージがある。
jhc
ガベージコレクションを使わないコードを出力するコンパイラ。jhc

実用では今のところ、GHCしか選択肢がないように思います。

クライアントアプリケーションを作るときは GUIライブラリも必要です。こなれているのは次の二つだと思います。

gtk2hs
gtk+2のHaskell binding.
wxHaskell
wxWidgets のHaskell binding. WxHaskell - HaskellWiki

ここではgtk2hsをインストールしてみます。

Windows

Windowsの場合は、先に MinGW 環境を整えます。MinGWのインストールは MinGWのインストール を参照してください。

次にGHCをインストールします。2008.11 現在、安定版の最新版はバージョン6.10.1です。

Windows用にバイナリ版が用意されているのでそれを利用します。インストーラをダウンロードしてきて実行します。

次はgtk2hsです。

gtk2hs は gtk2ライブラリを必要とします。先に Windowsネイティブなgtk2アプリケーションの開発 を参考に、インストールしておきます。

2008.11現在、Gtk2Hs の最新版はバージョン0.9.13です。

これもWindows用にバイナリ版が用意されています。インストーラをダウンロードして実行します。

Linux

Fedora 9 Linux には次のパッケージが用意されています。yum (または yumex) でインストールします。

GHCが最新の6.10.1ではないですが、最初は6.8.2でも問題ないと思います。

はろーわーるど・コンパイル

(2008.11.9 この節更新。)

まずはお約束のはろーわーるどから。

Haskellソースはファイル名の拡張子を .hs にします。GHCでは、文字コードはUTF-8 限定です。UTF-8以外の場合、コメント以外の場所に書けるのはASCIIだけです。

文字列リテラルは内部ではUnicodeで保持されますが、入出力の文字コードを指定する方法は、組み込みでは用意されていないようです。GHC 6.8.2 だと、UTF-8でも出力できなくて、ちょっと泣けます。

追加ライブラリについては、このあたりを参照; blog.kfish.org: Survey: Haskell Unicode support

さて、ハローワールドですが、こんな感じです;

[POPUP]
  1. {- Haskell "Hello World" -}
  2. main = putStrLn "Hello World!" -- putStrLn は文字列を出力する

コンパイルはghcコマンドです。オプションを何も付けないとリンクまでおこないます。コンパイルに成功すると a.out が出力されます。

$ ghc first.hs

インタプリタ

GHCには、インタプリタGHCiが付属している。ghciコマンドで起動できる。抜けるのは:quit。

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

Loading package base-1.0 ... linking ... done.
Prelude> 1 + 2 * 3
7
Prelude> "abc" ++ "def"
"abcdef"
Prelude> [1] ++ [4]
[1,4]
Prelude> [1] ++ [2,3]
[1,2,3]
Prelude> :quit
Leaving GHCi.

予約語

Haskellの予約語は、

case | class | data | default | deriving | do | else | if | import | in | infix | infixl | infixr | instance | let | module | newtype | of | then | type | where | _

これだけ。大文字・小文字を区別する。

引数のパターンマッチ

Haskell では、関数の名前が同じで引数が違うものを複数定義できる。

次のスクリプトは、リストの値を順番に表示する。

[]は空リスト、[x..y]は、xからyまでの値を含むリスト。[1..]と書くと、1以上無限の値を含むリストになる。

関数fooをオーバーロードし、空リストのときは上の関数を実行し、そうでないときは下の関数を実行する。

x:xsの「:」は演算子で、最初の引数を二つ目の引数であるリストの前に加える。関数の引数としては、リストを先頭の値xと残りのリストxsに分ける。

showは値を文字列に変換する(表示用)。

main = putStrLn (foo [1..])

foo []     = ""
foo (x:xs) = (show x) ++ "\n" ++ foo xs

何気なく無限リストを作ったが、エラーにならずに表示できる。

ガード (guard)

(2005.9.3)

関数を定義するとき、引数のパターンマッチで書く以外に、条件式でどの定義を使うかを選択するようにできる。

次のサンプルは階乗を計算する。

factorial :: Integer -> Integer     -- 関数宣言

factorial 0 = 1
factorial n = n * factorial (n - 1)

main = putStr (show (factorial 10))

これは、次のようにも書ける。その他の場合の定義は、| otherwise = ... と書く。

factorial n 
  | n == 0 = 1
  | n > 0  = n * factorial (n - 1)

関数をつなげる

関数をつなげる (.) や ($) も関数(演算子)です。

(.) :: (b -> c) -> (a -> b) -> a -> c
g . f x は、x に対して、f して g する。
($) :: (a -> b) -> a -> b
f $ g $ h x = f (g (h x))

コマンドラインオプション

Haskellスクリプトをコンパイルして実行したときに、コマンドラインオプションを取れるようにしたい。

do ... は、手続き型言語のように上から順に実行する。<- は変数に代入する。

import System          -- getArgs

main = do
  args <- getArgs      -- argsは[String]型になる
                       --     x <- getLine と書くと、コンソールから読み込む
  putStrLn (show args)

実行結果はこう。

$ ./main.exe foo bar --list=hoge
["foo","bar","--list=hoge"]

推薦図書

ふつうのHaskellプログラミング -- ふつうのプログラマのための関数型言語入門

(2007.1.19)

Haskellの初歩から文法、勘所まで着実、丁寧に解説した、非常に優れた本。これを読めばHaskellを読み書きできるようになること間違いなし。

Haskellの考え方に触れることで、Java / C++ / Ruby / Pythonなどほかのプログラミング言語でプログラミングするときでも再利用しやすく、保守しやすいコードを書く参考になる。

お薦め。

外部リンク

Learn You a Haskell for Great Good!
新しいチュートリアル。素敵。
Real World Haskell
書籍のテキストを一般公開。実用的な例が豊富。

トップ > 技術メモ (ソフトウェア開発) > はすけるで遊ぶ
このページについてのご感想・ご提案などをお寄せください。なお、コメントに「http:」、HTML aタグが含まれると送信されません。
評価: ◎ ← → ×
コメント:
お名前:
メールアドレス:
[Profile]  [Privacy Policy]  [Legal & Link]  [Site Map]  

banner Netsphere Laboratories http://www.nslabs.jp/

Copyright (c) HORIKAWA Hisashi. All rights reserved.

[PR]

はてなブックマークに追加  

サイト内検索:

[PR]