Haskell's archives

Debug.Traceを使ってprintf風デバッグ

in Haskell
by ginriki | 7 月 13th, 2007 

Haskell処理系であるGHCにはDebug.Traceモジュールというのが提供されています*1。その中のtrace関数を使うと、C言語のおけるprintfデバッグのようなことができます。

ただ、Haskellは遅延評価を行う言語なので、traceが呼び出されるタイミングに注意する必要があるそうです。

以下、参考元サイト

*1http://www.haskell.org/ghc/docs/latest/html/libraries/base/Debug-Trace.html :traceの実装自体は難しくないそうなので、他の処理系でも同じようなモジュールがあるかもしれません

Haskellだってバグるよねっていう話し(C言語の関数をHaskellで呼ぶ)

in FFI, Haskell
by ginriki | 7 月 9th, 2007 

C言語の関数をHaskellから呼び出すための記述に関する仕様が存在します*1

自分が使っているHaskell処理系のGHCは、この仕様に準拠しています。そこで、この機能を使ってバグったC関数をHaskellから呼ぶことでメモリアクセス違反させてみます*2

// foo.c
#include "HsFFI.h"

static int mem;

HsPtr wrong_ptr(int wrong)
{
if(wrong){
return (HsPtr)0xcfcfcfcf;
}else{
return (HsPtr)
}

}

このwrong_ptr関数を呼ぶHaskellコードは以下、

-- main.hs

import Foreign

foreign import ccall "wrong_ptr" wrong_ptr :: Int -> IO (Ptr Int32)

main = do
ptr <- wrong_ptr 0            -- 変数memのアドレスがptrを束縛する
pokeElemOff ptr 0 5           -- ptr[0] = 5
peekElemOff ptr 0 >>= print   -- 5を出力

ptr <- wrong_ptr 1            -- 0xcfcfcfcfがptrを束縛する
pokeElemOff ptr 0 100         -- メモリアクセス違反!!!
peekElemOff ptr 0 >>= print

で、実際にやってみると、*3

> ghc foo.c main.hs -ffi -o foo
> foo
5
<------ここで異常終了
>

この例はわざとらしいですが、Haskellのプログラムも、わかりにくいタイプのバグが入り込む余地があるっていうことがわかると思います。

C言語の関数を使わなきゃ良いっていう意見もあると思いますが、win32apiやらLinux等のシステムコールを直に扱いたい時には使わざる得ないでしょう*4

また、絶対にC言語の関数を使わないっていうスタンスは、既存のライブラリを使ったほうが楽なのに、わざわざHaskellで書き直さなきゃいけないといった問題が発生する点でコストが高いと思います。

個人的には、デバッグ周辺のツールがもう少し充実しないと、普通のプログラムを書くのにHaskellを使う気になれません。上の例よりもっと複雑なコードがバグった時のデバッグ作業を考えると恐ろしすぎます。

GHC6.7からはデバッガが付属するそうなので、正式にリリースされたら使ってみようと思います。

*1http://www.cse.unsw.edu.au/~chak/haskell/ffi/ffi.pdf

*2:このコードを書く際には、こちらの日記を参考にさせていただきました。http://d.hatena.ne.jp/E_Mattsan/20070616

*3:WindowsにmsiパッケージからGHCをインストールした場合、cc1が存在しないっていわれますが、C:/ghc/ghc-6.6.1/gcc-libにPATHを通せば動きます(GHC6.6.1をデフォルトのパスにインストールした場合)

*4:win32apiは、ある程度Haskellの標準ライブラリとして用意されてるようです

Haskell本の感想とMonad

in Haskell
by ginriki | 7 月 9th, 2007 

教養のために「ふつうのHaskellプログラミング」を読みました。Haskellを触ったことがない私のような人が読むのにちょうど良い本でした。

ただ、Monad則については読んでも良くわかりませんでした。Maybeモナド等、Monadインスタンスの使い方はわかるのですが、Monad則がどのようにして出てきて、どんな利点があるのか等の理論的な部分はページ量の関係か本に詳しく書いてありません。

そこで、Monadについて解説しているWebサイトを探して読んでみましたが、いまいち理解できてません。

ただ、IO処理等の副作用を持つ操作にMonadが利用できる理由については、以下のサイトを読むとなんとなくわかった気になれます。

ブログで紹介した商品

  • Image of デバッガの理論と実装 (ASCII SOFTWARE SCIENCE Language)