M.Hiroi's Home Page

Functional Programming

Haskell Programming

[ Home | Functional ]

WHAT'S NEW


CONTENTS


お気楽 Haskell プログラミング入門

CONTENTS

●初級編

●中級編

●応用編

●電卓プログラム編

●micro Scheme 編

●パズルの解法

●線形代数編


はじめに

Haskell は「遅延評価」を採用した純粋な関数型プログラミング言語です。一般に、副作用のない関数型言語を「純関数型言語」といいます。ML 系の言語 (Standard ML や OCaml) も関数型言語ですが、変数の破壊的代入や入出力処理などの副作用を許しているため、純関数型言語とはいえません。Haskell の場合、副作用がある処理は「IO モナド (IO Monad)」によって分離 (隔離) されているので、それ以外の処理は数学の関数 (数式) のようにプログラミングすることができます。

M.Hiroi は Haskell でプログラミングするのは初めてです。Haskell の特徴である「遅延評価」と「モナド」を使いこなすことができるように、簡単なプログラムを作りながら Haskell を勉強していきたいと思っております。まあ、初心者が作るプログラムなので、Haskell らしい綺麗なプログラムは書けないと思います。間違いやお気づきの点がありましたらご指摘いただけると助かります。たいしたことはできませんが、よろしければお付き合いくださいませ。

●ダウンロード

Haskell には複数の処理系がありますが、本ページでは GHC (Glasgow Haskell Compiler) を使うことにします。GHC は次のサイトからダウンロードできます。Windows 用のバイナリが用意されているので、簡単にインストールすることができます。

このほかにも Haskell をインストールする方法はいくつかありますが、ここでは Haskell のビルドツール Stack を使う方法を紹介しましょう。

Unix 系 OS の場合、本家 Web サイトに記載されているように、curl または wget を使って簡単にインストールすることができます。Windows 10 の場合、インストーラーが用意されているので、下記 Web サイトからダウンロードして実行するだけです。

あとはシェルで次のコマンドを実行すると GHC がインストールされます。

$ stack setup

GHC のインストールにはけっこう時間がかかるので注意してください。M.Hiroi は Ubunts 18.04 (WSL) にインストールしました。次のコマンドで Stack と GHC のバージョンを表示することができます。

$ stack --version
Version 2.5.1, Git revision d6ab861544918185236cf826cb2028abb266d6d5 x86_64 hpack-0.33.0
$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 8.8.4

Stack 経由で GHC を起動する場合、GHC に渡すオプションは -- の後ろに記述してください。-- の前に記述したオプションは Stack に渡されます。

●プログラムの実行

GHC はコンパイラ (ghc) とインタプリタ (ghci) があります。また、Haskell をスクリプト言語のように実行するためのコマンド runghc も用意されています。たとえば、シェルで ghci を起動すると、メッセージとプロンプト Prelude> が表示されます。Stack を使ってインストールした場合、プロジェクトを作らずに ghci を起動するときは stack exec ghci と入力してください。この状態で Haskell のプログラムを入力して簡単に実行することができます。終了する場合はコマンド :quit (または :q) か CTRL-D を入力してください。

$ stack exec ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/  :? for help
Prelude> 1 + 2 * 3
7
Prelude> :q
Leaving GHCi.
$

Stack でプロジェクトを作成し、そこで ghci を起動するときは stack ghci とします。そのプロジェクトの設定ファイルに合わせた ghci が起動されます。プロジェクトを作らない場合でも stack ghci で起動できますが、最初に注意書き (Note) が表示されます。

●簡単なベンチマーク

GHC はプログラムをネイティブコードにコンパイルするので、バイトコードにコンパイルする処理系よりもプログラムを高速に実行することができます。その実行速度ですが、たらいまわし関数を使って調べてみました。

リスト : たらいまわし関数 (Haskell)

module Main (main) where

import Data.Time

tak :: Int ->  Int -> Int -> Int
tak x y z =
  if x <= y then z
  else tak (tak (x - 1) y z) (tak (y - 1) z x) (tak (z - 1) x y)

-- 時間計測
main :: IO ()
main = do
  x <- getCurrentTime
  print (tak 22 11 0)
  y <- getCurrentTime
  print (diffUTCTime y x)

ファイル名を tak.hs とすると、シェル上で次のように入力すると実行ファイルを生成することができます。

$ ghc -O tak.hs

-O は最適化を指定するオプションです。Stack 経由で GHC を起動する場合は次のように入力します。

$ stack exec ghc -- -O tak.hs

exec を省略して stack ghc としてもコンパイルすることができます。

それでは実行結果を示します。tak 22 11 0 を計算しました。使用した GHC のバージョンは ver 8.8.4 です。

表 : tak 22 11 0 の結果
処理系
Python (ver 3.6.9)69.6
Lua (ver 5.3.3)37.2
Ruby (ver 2.5.1p57)25.4
Gauche (ver 0.9.9)25.3
ocamlc (ver 4.05.0)10.8
SBCL (ver 1.4.5)6.38
LuaJIT (var 2.1.0-β)4.02
SML/NJ (ver 110.98)2.66
Julia (ver 1.3.0)2.02
GHC (ver 8.8.4)1.96
SBCL (最適化)1.57
GCC -O2 (ver 7.4.0)1.23
ocamlopt (ver 4.05.0)0.97

GHC は SML/NJ や SBCL よりも速い結果になりましたが、GCC や OCaml にはかないませんでした。それでも、GCC にせまる速度をたたき出しているのですから、GHC は優れたコンパイラ (処理系) だと思います。

なお、たらいまわし関数には tak のほかにも tarai という関数があります。

リスト : たらいまわし関数 (2)

tarai :: Int ->  Int -> Int -> Int
tarai x y z =
  if x <= y then y
  else tarai (tarai (x - 1) y z) (tarai (y - 1) z x) (tarai (z - 1) x y)

関数 tarai は通称「竹内関数」と呼ばれていて、日本の代表的な Lisper である竹内郁雄先生によって考案されたそうです。そして、関数 tak は関数 tarai のバリエーションで、John Macarthy 先生によって作成されたそうです。

実をいうと、関数 tarai は「遅延評価」を行う処理系では高速に実行できることが知られています。実際に Haskell で tarai を実行すると、他の処理系とは比較にならないほど高速になります。興味のある方は試してみてください。


Yet Another Haskell Problems


参考文献と URL

  1. Miran Lipovaca (著), 田中英行, 村主崇之 (共訳),『すごい Haskell たのしく学ぼう!』, オーム社, 2012
  2. Miran Lipovaca, 『Learn You a Haskell for Great Good!』(英語)
  3. Paul Hudak, John Peterson and Joseph Fasel (著), 山下伸夫 (訳), 『やさしい Haskell 入門 (バージョン98)
  4. Sampou.Org
  5. 日本Haskellユーザーグループ - Haskell-jp

Haskell Programming (お気楽 Haskell プログラミング入門を含む本ページ) の著作権は筆者「広井誠 (Makoto Hiroi)」が保持します。無断使用や無断転載は禁止いたします。Haskell Programming で作成したプログラムはフリーソフトウェアとします。ご自由にお使いください。プログラムの改造や配布もご自由にどうぞ。その際は、出典を明記してくださるようお願いいたします。

ただし、これらのプログラムは無保証であり、使用したことにより生じた損害について、作者「広井誠 (Makoto Hiroi)」は一切の責任を負いません。また、これらのプログラムを販売することで利益を得るといった商行為は禁止いたします。

Copyright (C) 2013-2021 Makoto Hiroi
All rights reserved.

[ Home | Functional ]