閉じる

本物のプログラマはHaskellを使う

日経ソフトウエア
日経ソフトウエア

目次

  • 第38回 書き換え規則を強力にサポートする段階制御

     前回で説明した書き換え規則は,プログラムの実行を効率化するのに有用です。しかし,書き換え規則が意図どおりに動かなかったり,書き換え規則を使用することで思わぬ結果が生じたりすることもあります。今回は,そうした問題を解決するのに役立つ「段階制御」という機能を取り上げます。

  • 第37回 書き換え規則を使って不要な計算や中間データを除去

     プログラムの処理は,いつも効率的であるとは限りません。非効率的な処理があれば,別の効率的な処理に置き換える必要があります。GHCには,プログラマが最適化の方法を処理系に指示するための「書き換え規則(Rewrite Rules)」という機能があります。今回は,書き換え規則の基本的な使い方と,GHCに…

  • 第36回 Int型のキーに特化したIntMap型

     Haskellでは,様々な型のキーを使用できるMap型を辞書として利用できますが,特定の型に最適化された別のデータ型も用意されています。contaniersパッケージのData.IntMapモジュールは,Int型のキーに特化したデータ型である「IntMap型」を提供しています。今回はIntMap型…

  • 第35回 キーを使って値を参照するMap型

     プログラムを書いていると,キーと値を組にしてデータを保持する辞書のデータ構造を使いたくなることがあります。Haskellではこのようなとき,containersパッケージのData.Mapモジュールに用意されているMap型などの「木を使ったデータ型」をよく使います。今回はMap型を紹介します。

  • 第34回 様々なデータ構造でfoldを使えるようにするFoldableクラス

     データ構造の中のすべての要素にアクセスする高階関数には,mapとfoldの大きく二つがあります。mapは様々なデータ構造で利用できるようFunctorクラスを使って一般化されていますが,foldも様々なデータ型に対して扱えるよう型クラスを使って一般化されています。今回は,foldを一般化するFol…

  • 第33回 木構造のSeq型を効率よく操作する

     前回,Seq型の要素はviewl関数またはviewr関数を使って参照することを説明しました。viewlやviewrを利用すると,リストに対して用意されている様々な関数と同様の機能を持つ関数をSeq型に対して定義できます。しかし,viewlやviewrを使って実装した関数は,Seqを左端または右端か…

  • 第32回 効率的なキューを表現するSeq型

     効率的なプログラムを書くには,その処理に適したデータ構造を利用しなければなりません。これまでは,リストや配列といった組み込みのデータ型を主に扱ってきました。しかし,処理によってはリストや配列の代わりに「キュー(queue,待ち行列とも呼ぶ)」や「両端キュー(double-ended queue,d…

  • 第31回 禁断の機能「unsafePerformIO」の深淵

     Haskell以外の言語に慣れ親しんでいる人は,プログラムがIOモナドに閉じこめられてしまうHaskellのプログラミングを窮屈に感じるかもしれません。そうした人にとって,unsafePerformIOはこの窮屈さを取り除いてくれる頼もしい味方に見えるでしょう。しかし,unsafePerformI…

  • 第30回 状態を扱う複数のモナドを合成したRWSモナド

     状態を扱うStateやST,ReaderやWriterといったモナドを複数組み合わせて利用したい場合があります。まず思いつく方法は,モナド変換子を使って複数のモナドを合成することでしょう。ただし,モナド変換子を使う方法がいつでも最適だとは限りません。モナド変換子以外に,複数のモナドの能力を併せ持つ…

  • 第29回 グローバル変数の代わりに使えるReaderモナドとWriterモナド

     Haskellでは,グローバル変数の使用による副作用の発生を防ぐため,グローバル変数として使える可能性のある機能は,IOモナドやSTモナドといった特定のモナドでしか利用できないようになっています。しかし,ときにはグローバル変数に頼りたくなることもあるでしょう。そんなときでも,本物のグローバル変数を…

  • 第28回 例外やエラーに対する処理能力を加えるエラー・モナド

     Haskellの例外処理は,IOやSTMといった特定のモナドの内部でのみ扱えるようにデザインされています。しかし,こうした制限が行き届くのは,あくまで例外を捕捉し処理する場面に限られます。ありとあらゆる場所で発生する可能性のある例外やエラーに対する処理をより統一的に扱うにはモナド変換子を利用します…

  • 第27回 外部環境のエラーとHaskellの間の整合性を取る

     FFIを使ってHaskell以外の言語からライブラリを使おうとした場合,別の言語で書かれた関数は,別の言語の仕様や慣習に従った形でエラーまたは例外を通知します。このため,FFIを使って呼び出す処理がエラーや例外を発生させる場合,エラーや例外を適切なものに変換することで整合性を取る必要があります。今…

  • 第26回 例外の「中断・終了処理」としての側面

     例外の発生は,Haskellを含む多く言語にとって,それまで行っていた計算の強制的な中断・終了を意味します。例外の発生による計算の中断は,並行処理,中でもSoftware Transactional Memory(STM)ではどのような意味を持つでしょうか? また,例外の発生による計算の中断をより…

  • 第25回 Haskell流の例外処理を学ぶ

     Haskellの静的な型検査は強力ですが,プログラムの実行時に起こり得るすべての問題を解決できるわけではありません。実行前に静的に解決できない問題は,実行時に動的に解決する必要があります。このための手段を提供するのが例外処理です。例外処理については,これまで何度か断片的に説明しましたが,全体像をま…

  • 第24回 マルチスレッド環境下でのFFIの利用

     並行処理の存在は,プログラムやそれを記述するための言語仕様に対して,良くも悪くも影響を及ぼします。FFIも例外ではありません。FFIの仕様やFFIを使ったプログラムを並行処理しようとする場合,きちんと考慮しなければうまく動作しない可能性があります。

  • 第23回 外部環境のメモリーとHaskellの間の整合性を取る

     前回はFFIのごく基本的な使い方について説明しました。実際のプログラミングでFFIを用いる場合には,もう少し突っ込んだ知識が必要になります。「Haskell内部の環境と,FFIを使って呼び出されるべき外部の環境との違い」,これをどのように解決するかを考えなければなりません。こうした違いには「リソー…

  • 第22回 FFIを使って他の言語の関数を呼び出す

     Haskellを使ってアプリケーションを作成しようとすると,ライブラリの機能不足に遭遇することがあります。不足しているこうした機能の中には,C言語で書かれたライブラリやOSのAPIなどの力を借りなければ記述できないものがあります。このためHaskellでは,実行環境の外にある他言語のライブラリを扱…

  • 第21回 更新操作を一般化するためのSTモナド

    前回はSTモナドの基本的な特徴やSTモナドとかかわりのある拡張機能について説明しました。今回はそれらの知識を基にして,「STモナドのインタフェースとして提供されている関数」と「STモナドのさらなる性質」を説明します。

  • 第20回 更新を高速化するためのSTモナド

     これまで何度かSTモナドについて言及してきましたが,まとまった説明はしてきませんでした。そこで今回から2回にわたってSTモナドの詳細を解説していきます。今回は,STモナドの基本的な特徴,およびSTモナドと関係のある拡張機能について説明します。

日経 xTECH SPECIAL

What's New!

経営

クラウド

アプリケーション/DB/ミドルウエア

運用管理

ネットワーク/通信サービス

セキュリティ

もっと見る