haskellでlivedoor clipのRSSをとってきてパースする

普段やるようなことをHaskellで書くようにすればよかろうとHaXmlhttpをつかってみた。

ほとんどhttpのテストサンプルのget.hsだけど。HaXmlのほうはHaXml の Combinators を使って XML をいじるを参考にした。

import Data.Char (intToDigit)
import Network.HTTP
import Network.URI
import System.Environment (getArgs)
import System.Exit (exitFailure)
import System.IO (hPutStrLn, stderr)
import Text.XML.HaXml
import Text.XML.HaXml.Xml2Haskell
import Text.XML.HaXml.Pretty

main = 
    do
    args <- getArgs
    case args of 
    [addr] -> case parseURI addr of
                   Nothing -> err "Could not parse URI"
                   Just uri -> do
                               cont <- get uri
                               elems <- fGetElem "test" cont
                                   mapM_ (print . content) $ (deep $ tag "title") elems 
    _ -> err "Usage: get <url>"

err :: String -> IO a
err msg = do 
      hPutStrLn stderr msg
      exitFailure

get :: URI -> IO String
get uri =
    do
    eresp <- simpleHTTP (request uri)
    resp <- handleE (err . show) eresp
    case rspCode resp of
                      (2,0,0) -> return (rspBody resp)
                      _ -> err (httpError resp)
    where
    showRspCode (a,b,c) = map intToDigit [a,b,c]
    httpError resp = showRspCode (rspCode resp) ++ " " ++ rspReason resp

request :: URI -> Request
request uri = Request{ rqURI = uri,
                       rqMethod = GET,
                       rqHeaders = [],
                       rqBody = "" }

handleE :: Monad m => (ConnError -> m a) -> Either ConnError a -> m a
handleE h (Left e) = h e
handleE _ (Right v) = return v

fGetElem fname cont = return (CElem elems)
                 where Document _ _ elems _ = xmlParse fname cont

xmlParseにファイル名入れなきゃいけないので適当に名前をいれといた。

Text.XML.HaXml.Parse

xmlParse :: String -> String -> Document To parse a whole document, xmlParse file content takes a filename (for generating error reports) and the string content of that file. A parse error causes program failure, with message to stderr.

なんか良く分からんが。

実行するとタイトルだけ抜き出すはず。

$ ./rssparse http://clip.livedoor.com/rss/clips/fmkz336
<title>fmkz336のクリップ - livedoor クリップ</title>
<title>haxml.pdf (application/pdf オブジェクト)</title>
<title>CategoryBinaries - DarcsWiki</title>
<title>PLEAC-Haskell</title>
<title>AIRアプリはドラッグ&ドロップでこんなことまで!(1/3) ─ @IT</title>
<title>Javascript でタートルグラフィックス - 言語ゲーム</title>
<title>[Haskell][30分プログラム]テトリスっぽい何か</title>
<title>ほにゃ。</title>
<title>はたしてバイオはオープンか?(Re:研究とかをオープンにすること) - バイオ研究者見習い生活 with IT</title>
<title>[REST][書きかけ][WebService][SOAP] RESTful な blast 検索サービスを作るとしたらどうするかを考えてみた</title>
<title>こういうことがしたいんだけど - 刺身☆ブーメランのはてなダイアリー</title>
<title>Version Control with SVK</title>
<title>svkでもう少し攻めてみる</title>
<title>Programming:WayToHaskeller</title>
<title>TM23Proof.pdf (application/pdf オブジェクト)</title>
<title>サーバーのリソースを定期的に取得する - Hatena::Diary::Ubuntu</title>
<title>モナドのすべて - Enjoy Programming</title>
<title>howm wiki - モナド</title>
<title>好きなフォント</title>
<title>Pexpect - a Pure Python Expect-like module</title>
<title>wxPython Cookbook - wxPyWiki</title>

HTTPのほうは読めば分かりそうなもんだけど、HaXmlはなかなか簡単なサンプルがなかったので難儀した。

HaskellでNetwork.HTTPを入れてみた

perlでいうところのLWPでいいのかな。標準では入ってなかったのでここから。windowsにはdarcs入れてなかったのでlinuxの方にインストール

$ darcs get http://darcs.haskell.org/http/
$ runhaskell Setup.lhs configure
$ runhaskell Setup.lhs build
$ runhaskell Setup.lhs install

これでOK。あとはtestデイレクトリにget.hsっていうサンプルがあるので、コンパイルして動かしてみる。そのあとソースを眺めて理解する(それはこれから)

で、その後RESTなURIにでもアクセスしてみて受け取ったXMLをパースしてみる予定。

余談だが、fedora8だとdarcsはyumから入れられる。

yum install darcs

でオッケーだったような。

Haskellのインデント

下の感じのコードを書いたら、

do let ...
   if ... then
      ...
   else
      ...

インデント間違えてへんか?みたいなエラーが出まして、どうも、elseは ifよりも下げないといけないようだ、Haskell的には。

なんでifとelse揃えたらあかんのやー

WikiBookのdo within ifってところに書いてあった。doのなかでインデント揃えちゃうと;が入ってるものとみなされるから

do { first thing
   ; if condition
   ; then foo
   ; else bar
   ; third thing }

と解釈されてしまうらしい。

構文解析器結合子

今週末は娘が昼寝をしなかったので、自分の時間がほとんどとれず。 しかも今日などは娘は寝なかったのに僕のみお昼寝をするという失態をやらかしてしまった。

やらかしたというよりはプログラム・プロムナードの2006年2月号を読んでうーんとうなっているうちに睡魔に襲われ、落ちてしまったというところ。

Stateモナド

おーなるほどー。

そしてまたモナドのすべてを読む

Haskellで継続

Haskell - WikiBookを読んでる。

継続のあたりまで進んだのだけど、動かすのに困ったのでメモ。説明は分かりやすかった。あと、Haskell-modeはミニバッファに型が出てきて便利。いちいち:tとかやって確認するの面倒だし。

import Control.Monad.Cont

foo :: Int -> Cont r String
foo n =
  callCC $ \k -> do
    let n' = n ^ 2 + 3
    when (n' > 20) $ k "over twenty"
    return (show $ n' - 4)

-- runCont (foo 5) id

そしてさらに、Haskellの継続モナド(Continuation Monad)を理解するポイントも併せて読んで吉。

wikibookはarrowのとことかも分かりやすかった。

入門Haskellさめがめ中

6.3まで。隣り合ったマスを再帰でマークしていくあたりとか、おーなるほどと。この章はコード書くときの流れ的なものが感じられておもしろいです。

ProductName 入門Haskell―はじめて学ぶ関数型言語
向井 淳
毎日コミュニケーションズ / ¥ 2,730 (2006-03)
通常24時間以内に発送

あとこれって3次元に拡張すれば、結構簡単に蛋白質のリガンド結合ポケットの穴をグリッドで表現出来そうじゃんと。今度やってみようかな。再帰は素敵だ。

wxHaskell入れた

入門Haskellの6章はsamegameをつくろうの章だ。

haskellの標準GUIのHGLで簡単なサンプルでもと動かそうとしたら、動かん。どうもWindowsでは標準から外されたらしい。

あらーん、ということで、じゃぁwxHaskellでもと思ったが、こっちもなんか開発とまってんの?って感じで最新のHaskellには対応してなさげ。コンパイルすればいいのかねー。うーん。

と悩んでいたら、6.8.1だったらOKらしい。おーありがたいと早速入れた。

で、入門Haskellのサイトのwxsamegameを動かしてみた。

samegame

ちゃんと動いてるよ!。ちょっとうれしい。

入門Haskell買った

昨日TOEICがあったので先週はiKnowばっかやってた。TOEICの出来は微妙なとこだけど、ちょっとiKnowの効果は出たみたい。ディクテーションよいですな。あと単語力上げるのにもいいが、やっぱdiaryをつけねばならんね。

で、合間に本物のプログラマはHaskellを使うとかHaskellプログラミング読んだりとか。っつーかこっちのほうが難しすぎ。2005-8のメモ化の話で何日か考え込んでた。

さて、英語もひと段落したので年始からはまりっぱなしのHaskellでもと、入門Haskellを購入して読むことにした。

ProductName 入門Haskell―はじめて学ぶ関数型言語
向井 淳
毎日コミュニケーションズ / ¥ 2,730 (2006-03)
通常24時間以内に発送

一気に4章まで読んだ。明日は通院なので待ち時間に5章のモナドのとこ読みつつ、サメガメ作り(6章)をやる予定。

少しいろいろやってみてからこの本を読むと面白さが伝わってきてよい。解説のとことか、ほーなるほど、あーそうなんだと思うようなことが多かった。ふつけるはHaskellを知ろうっていう構成なのに対して入門HaskellはHaskellで書こうって感じの本だなぁという印象。

で、Haskellでもっと書こうって思ったときにこの先何を読めばよいのかわからんなーってのがHaskellの悩みどころですな。

とかやってみて、

  • ParsecでPDBパーサーを書いてみる
  • HappSいじってみる

とかかなぁ。perlとかpythonは探せば(上達の)階段らしきものは得られるのに、Haskellだと、いきなり20階ぐらい上にエレベーターで飛ばされる気分なんだよな。この間を埋めるいい書籍とかWebの情報はないのかなー。

MeadowでHaskell

最近のhaskell-modeはhaskell-site-fileをロードするだけでよいらしい。.emacsに書いておいた。

(load "c:/Meadow/site-lisp/haskell-mode-2.4/haskell-site-file.el")

これで、C-cC-lでghciが起動してファイルをロードしてくれるので楽だ。 今はHaskellプログラミングを読んだり解いたりしてる。ちなみに和田先生のルービックキューブのやつとか難しくてわからんのでスキップしたが、その次のメモ化の章はやたらとおもしろい(まだ消化してないけど)

type State s t = s -> (t,s)

とかやって関数の型を抽象化してるんだけど、いまいちついていけない自分の理解力がもどかしい。

Next Page