2010-01-01から1年間の記事一覧

一旦中止

約3ヶ月ほどふつうのHaskellプログラミングを読みながら勉強してきました。 自分なりに関数プログラミングとは何かを垣間見たように思いましたが、まだまだですね。 もうちょっと続けたかったのですが、仕事のカラミで勉強内容を変更します。 明日からはAndr…

Wikiエンジンの開発

13.3 CGIの処理 昨日までで、"runCGI"関数の中の"cgiEnvs"関数まで解析が終わりました。 次は"runCGI"関数の心臓部である"parseCGIRequest"関数を見ていきます。 "parseCGIRequest"関数の定義を見てみます。 parseCGIRequest env input = case method of "GE…

Wikiエンジンの開発

13.3 CGIの開発 今日は"mGetEnvPair"関数の続きです。 昨日は"mGetEnvPair"関数の前半戦では、環境変数の名前をもらって、 IO (Maybe (環境変数名, 環境変数の値)) というIO型のMaybeタプル(アクション)を生成しました。 ※昨日の記事は間違っていました。 …

Wikiエンジンの開発

13.3 CGIの処理 昨日は"sequence"関数を追跡しました。 "sequence"関数は、たとえば [Just 1, Just 2, Just 3] -- → Just [1, 2, 3] [IO "ab", IO "cd", IO "ef"] -- → IO ["ab, "cd", "ef"] という変換をすることが分かりました。 本日は"mapM"関数を見てい…

Wikiエンジンの開発

13.3 CGIの処理 いろいろ混乱してきたので今日はひとまず"mcons"関数をしっかり理解しよう。 でも"mcons"関数だけを見て理解しようとしても難しいです。 そこで、"sequence"関数を簡単な引数に適用してみて感じを掴みとってみよう。 "sequence"関数に与える…

Wikiエンジンの開発

13.3 CGIの処理 今日は"cgiEnvs"関数を見ていきます。 定義はこんな感じ。 cgiEnvs = return . catMaybes =<< mapM mGetEnvPair names where mGetEnvPair :: String -> IO (Maybe (String, String)) mGetEnvPair name = catch (return . Just . (,) name =<<…

Wikiエンジンの開発

13.3 CGIの処理 さて本日は"runCGI"関数です。 これはなかなかヘビーな関数です。 いつものようにのんびり見ていこう。 まずは定義です。 CGI.hs runCGI :: (HTTPRequest -> IO HTTPResponse) -> IO () runCGI f = do hSetBinaryMode stdin True hSetBinaryM…

Wikiエンジンの開発

13.3 CGIの処理 本日は"reduce"関数です。 定義はこんな感じ。 reduce :: Config -> (String, Config) reduce kvs = (category . fst . head $ kvs, map (\(k,v) -> (itemname k, v)) kvs) ちょっと複雑です。一つ一つ見ていきます。 その前に、"reduce"関数…

Wikiエンジンの開発

13.3 CGIの処理 さて本日は"categorize"関数に挑戦します。 定義はこんな感じ。 Config.hs categorize :: Config -> [Config] categorize = groupBy (\(a,_) (b,_) -> category a == category b) その前に確認。 "categorize"関数が適用される値は以下のよう…

Wikiエンジンの開発

12.3 CGIの処理 本日は"isSpace"関数を見ていきます。 それにしても、こうやってゆっくり見ていくのもいいものですね。 一つ一つ丁寧に見る気になります。 この本が読み終わったら、他のオープンソースのコードを見ていくのも面白いかも知れませんね。 閑話…

Wikiエンジンの開発

12.3 CGIの処理 loadContextの続き 今日は"foldr"関数です。 でも"foldr"関数だけを見ると逆に分かりにくいのである程度まとめてみていきます。 foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) and = fol…

Wikiエンジンの開発

12.3 CGIの処理 loadContextの続き まだまだ続きます、loadContext。 昨日は"dropComment"関数まで見ました。 今日は"parseLinePlain"関数です。 "parseLinePlain"関数の定義はこんな感じ。 parseLinePlain line | isBlank line = [] | otherwise = let (k, …

Wikiエンジンの開発

12.3 CGIの処理 loadContext続き 昨日の続きです。 昨日は"parseConfigFile"関数にたどり着いた時点で終了でした。 "parseConfigFile"の中で呼び出されている関数を見ていきます。 まずは"parseLine"から。 ちなみに"parseLine"関数の引数は "./config"ファ…

Wikiエンジンの開発

12.3 CGIの処理 まず始めはmainアクションからです。 main = do ctx <- loadContext "./config" runCGI (appMain ctx) シンプルですね。 日本語的に書くと、設定ファイル"./config"を読み込んで、runCGIを引数appMain ctxに適用する。 では一つ一つ見ていこ…

Wikiエンジンの開発

12.1 第3部の目的 いよいよ終盤戦に入りました。 これまで勉強してきたことの応用です。 ということで、ここではWikiのソースコードのインストールをします。 まずはここからソースコード一式をダウンロードします。 私はLinux上で勉強してるので、Linux用の…

モナド

11.6 本章のまとめ ようやくモナドの章が終わります。 Maybe、[]、IOと見てきましたが、(合っているかどうか微妙なところですが) どれも難しいですね。 油断すると見失ってしまう感じです。 今の理解で第3部に進んで、理解を頭に馴染ませる必要があります…

モナド

11.5 モナドの構文 let節について あいやぁ、もうすでに忘れていました、let節。。。 急いで前に戻って復習しました。 なるほど、C言語などのローカル変数宣言のようなものですね。 これをdo式の中で使おうとするとコンパイルエラーになってしまいます。 そ…

モナド

11.5 モナドの構文 はまる… do式のサンプルを作ってみたところ、見事にハマってしまいました。 こんな感じ。 do_example.hs config :: [(String, [(String, String)])] config = [ ("database", [("path", "/var/app/db"), ("encoding", "euc-jp")]), ("urlm…

モナド

11.4 IOモナド う〜ん、昨日は一日中(というと大げさですが)考えてしまいました。 IOモナド。 何だかよく分かりません。 ここのIO型の定義を見ても… instance Monad IO where (>>=) = ... return = ... fail s = ioError (userError s) 「...」って何だ? …

モナド

11.4 IOモナド Maybe、[](リスト)型クラスでは、(>==)とreturnを使ってモナドを理解しました。 そして最後はIOモナドです。 でもやっぱり難しい。ここでもじっくり理解してみます。 評価順序と参照透明性 まずは評価順序。 IOモナドの関数は、戻り値として…

モナド

11.3 リストモナド リストモナドも難しい。 分かったようでいて分からないもやもや感。 時間をかけて、考えてみる。 具体例で試してみる いつものようにNonsenseな例を作ってみます。 {-- 階乗のリストを作成する。 階乗のリストって何ていうんだろう? --} …

モナド

11.2 Maybeモナド ちょっと復習 前回、関数がMaybe a型戻り値を返すことで続く関数を実行しないことが可能と書きました。 まぁ、模式的に書くとこんな感じ。 func a -> Maybe a -> Maybe a func a Nothing = Nothing func a (Just b) = 何らかの計算結果を返…

モナド

11.1 モナドとは何か う〜ん、モナドの定義だけでは分かりません。難しいです。 やっぱり具体例がないと分かりませんね。 Monadクラスの定義とモナド則を頭の片隅に置きつつ、次に進みます。 11.2 Maybeモナド いつぞやbさんにコメントで書いて頂いたMaybeが…

モジュール

10.3 インポート qualifiedやasを使ってみる。 さて最後にqualifiedやasを使って、昨日exportしたものを使ってみます。 こんな感じ。 FileUtils.hs {-- ファイル操作用モジュール(実際には違うけど…) --} module FileUtils (SomeType(ConsA, ConsB), Another…

モジュール

10.1 モジュールの基本概念 HaskellはJavaでいうところのパッケージ、Cでいうところのライブラリに当たるものですね。 モジュールが分かれていれば同じ関数名などのエンティティがあってもいいんですね。 モジュールの使い方を勉強したら試してみよ。 10.2 …

型と型クラス

9.5 本章のまとめ なるほど、たしかにHaskellの型クラスはJavaのインターフェイスに似ていますね。 では練習問題に進みます。 9.6 練習問題 うぅ、今回の練習問題、多いですね。一つ一つじっくりやっていきましょう。 まずは一つ目の問題。こんな感じかな。 …

型と型クラス

9.4 型クラス class宣言とinstance宣言について この二つを使いこなせば、ある程度オブジェクト指向プログラミングがHaskellで出来るのではないか? と思いました。 今後いろいろ遊んでみようかな。 とりあえずこんな感じ。 main = do print tag data Font =…

型と型クラス

9.4 型クラス オブジェクト指向でクラスというキーワードはよく出てきますが、 Haskellにおける型クラスはオブジェクト指向におけるクラスとはちょっと異なるものですね。 型の分類とでも言いましょうか。型のグループとでも言いましょうか。 アドホックとは…

型と型クラス

9.3 型の別名と付け替え newtype宣言について 昨日時間切れで作りきれなかったnewtype宣言のサンプル。 まぁ、悩んだ分理解が深まりました。 example5.hs newtype MyListNT a = MkMyListNT [a] myList :: MyListNT Int myList = MkMyListNT [1, 2, 3, 4] top…

型と型クラス

9.3 型の別名と付け替え type宣言とnewtype宣言について type宣言は分かりやすいですね。C言語でいうところのtypedefのようなノリですね。 type MyInt = Int myData :: MyInt myData = 17 type MyArray a = [a] type MyIntArray = MyArray MyInt myArray :: …