fc2ブログ
  1. Top » 
  2. Haskell

【Haskell】コマンドライン引数の取得を活用する。

しばらく取り組んでいるブログに役立つプログラム作りのために、少し脇道にそれて頑張る。
普通にコマンドライン引数を取得して出力するだけなら

import System
main = do args <- getArgs
print args

こんな風に書ける。ちなみにこのプログラムは簡単に書くと

import System
main = getArgs >>= print

こんな風にも書ける。簡単バージョンだな。
またgetArgsの出力は文字列のリスト、[String]で得られる。

ところでGHCの吐き出すexeファイルにファイルを1つ、もしくは複数個D&Dすると
その絶対パスのリストが得られることが分かった。
これをうまく解析してやれば、Ver.1のプログラムをもう少し改善出来そうだ。
というわけでドラッグ&ドロップされたファイルのパスのリストの取得&出力をするプログラムを書く。

import System
main = do getArgs >>= printArgs
getChar >>= print

printArgs :: [String] -> IO ()
printArgs (f:l) = do putStrLn f
printArgs l
printArgs [] = putStr ""

このような関数定義はパターンマッチをうまく使うと綺麗に書ける。
(パターンマッチについてはまだ書いてないのでそのうち)

少し解説すると、一つ一つは簡略バージョンの描き方。
またgetCharとprintのコンビは、コマンドプロンプトがすぐに閉じないようにするために入れてある。


これをすると、1つまたは複数個のファイルをD&Dしたとき、そのパス名リストを出力してくれる。
また今回はgetArgsを使ったが、どうもgetContentsのままでもこれは出来るらしく
こういったのを組み合わせてブログの記事リスト作りプログラムを改良する。


category of Haskell:
Haskell】とても簡単なHaskellプログラムについて
Haskell】標準入力(stdin)を読み込むために
Haskell】結構頻繁に使う関数などの話
Haskell】高階関数と型の定義について
【Haskell】リストの処理について
【Haskell】コマンドライン引数を得る方法
【Haskell】C言語の構造体のようなものをHaskellで利用する
【Haskell】Haskellを使ってブログに微妙に役立つプログラムを書きたい(Ver.0)
【Haskell】Haskellを使ってブログに微妙に役立つプログラムを書きたい(Ver.1)
スポンサーサイト



【Haskell】Haskellを使ってブログに微妙に役立つプログラムを書きたい(Ver.1)

さて、前回の記事で作ったHaskellプログラム。いろいろと突っ込みどころがあります。
要するに「標準入力から読み込んで、HTMLソースを標準出力に出す」という制限の部分です。
だってあなた(自分)、ブログ書くときにコマンドプロンプト使うの?っていうことですよね。
確かにコマンドプロンプト自体はよく使うものですが、別にブログを書くときにまで使いたくはないですよね。
というわけでここを改善していきます。最低限利用できるプログラムにします。


どのように改良するのか。せっかくGHCはexeファイルを吐き出してくれる。
ですからファイルから読み込んでファイルから書き出すようないっぱしのプログラム形式にしてみたいわけです。
exeファイルとして使えるようになるので


  • exeファイルと同じところにあるsrc.txtというテキストファイルにリストを書いておく
  • このリストを読み出して、HTMLソースを作成する(前回のプログラム)
  • 最終的にexeファイルと同じところにあるhtmlsrc.txtに書き出す


このようにすればまだ使える感じがしてきますね、プログラムっぽいです。
というわけで前回のプログラムをうまく再利用しながらやっていきます。


前回のプログラムを再利用できるところ
getHtml :: String -> String
getHtml h = let wh = words h
number = head $ wh
title = head $ tail $ wh
in do "<a href=\""
++ hreftp
++ number
++ ".html\"><strong>" ++ title ++ "</strong></a>"

リストからHTMLソースにする部分。ここはそのまま使えます。
結局標準入力と標準出力を使う代わりにファイル入力とファイル出力を使えばいいのです。


ファイル入出力はIOパッケージで利用できるのですが、いわゆる例外が発生します。
こんなファイルありませんよ?とか、このファイルには書き込めませんよ?とかいうやつです。
こういった実行時例外などへの対処は、本当はちゃんと書かないといけないところだと思います。
がしかし、結局自分が使うプログラムであるから、手の抜けるところは手を抜くという方針です。
よってこういったところは少し目をつぶり、とにかく簡単なファイル入出力をします。
まず次のように宣言します。

import IO
infile = "src.txt"
output = "htmlsrc.txt"

IOを使えるように、また入力ファイル名と出力ファイル名を固定しておきましょう。
さて、次のようにファイル入出力を行うプログラムは書けます。

main = do cs <- readFile infile
outhandle <- openFile output AppendMode
hPutStrLn outhandle header
hPutStr outhandle $ unlines $ map getHtml $ lines cs
hClose outhandle

簡単ながら説明していきましょう。

1.もっとも簡単でシンプルなファイル入力
標準入力を取ってくるgetContentsというものがありました。
また実行時引数を取ってくるgetArgsというものもあります。
これと似たように、簡単なファイル入力にはreadFileという関数が利用できます。

cs <- readFile filename


このようにすることで、あたかもgetContentsしているようにファイルから入力できます。
前に言っているとおり、細かい例外の処理などはありません。
このようにして持ってきた入力csをver.0のように処理することでHTMLを生成できます。

2.簡単なファイル出力の準備
出力時、今回は現在存在しているファイルの末尾に書いていくという追加書き込みを利用します。
C言語風に言うと”a”というモードで、HaskellではAppendModeという表現がされます。
こういったものを扱うために、ハンドラと呼ばれるものを経由した書き込みを行います。
ハンドラの宣言は次のように行われています。

outhandle <- openFile output AppendMode


変数名outhandleで、openFileというのがデータコンストラクタです。
データコンストラクタについては【Haskell】C言語の構造体のようなものをHaskellで利用するで書きました。
このデータコンストラクタにファイル名とハンドラのモードを与えることでファイル書き込みのための準備をします。

3.実際にファイル出力をする場所
標準出力putStrLnとputStrに対応するファイル書き込みようの関数がhPutStrLn及びhPutStrです。

hPutStrLn handler STRING
hPutStr handerl STRING


のようにすることでSTRINGをhandlerで設定しているファイルに書き込むことが出来ます。


4.後片付け
書き込みを行った後、hCloseという関数でハンドラの後処理を行います。
これを行わないと書き込みがちゃんと完了しないといった現象が発生します。


実行
さて、このようにして作成したプログラムに、リスト

3 【Haskell】とても簡単なHaskellプログラムについて
8 【Haskell】標準入力(stdin)を読み込むために
36 【Haskell】結構頻繁に使う関数などの話
37 【Haskell】高階関数と型の定義について
489 【Haskell】リストの処理について
509 【Haskell】C言語の構造体のようなものをHaskellで利用する
511 【Haskell】Haskellを使ってブログに微妙に役立つプログラムを書きたい(Ver.0)


をsrc.txtとして置いておき、プログラムを実行して生成されるファイルhtmlsrc.txtからのコピペを張って終わります。


category of Haskell:
【Haskell】とても簡単なHaskellプログラムについて
【Haskell】標準入力(stdin)を読み込むために
【Haskell】結構頻繁に使う関数などの話
【Haskell】高階関数と型の定義について
【Haskell】リストの処理について
【Haskell】コマンドライン引数を得る方法
【Haskell】C言語の構造体のようなものをHaskellで利用する
【Haskell】Haskellを使ってブログに微妙に役立つプログラムを書きたい(Ver.0)

【Haskell】Haskellを使ってブログに微妙に役立つプログラムを書きたい(Ver.0)

Haskellの話のように、連続的に書いているような記事はよくあります。
そのとき、たとえばHaskellの記事であれば


category of Haskell:
【Haskell】とても簡単なHaskellプログラムについて
【Haskell】標準入力(stdin)を読み込むために
【Haskell】結構頻繁に使う関数などの話
【Haskell】高階関数と型の定義について
【Haskell】リストの処理について
【Haskell】コマンドライン引数を得る方法
【Haskell】C言語の構造体のようなものをHaskellで利用する


こんな感じの記事リストを付けていることがある。
実はこのリストは、いつもちまちまとHTMLのコードを自分で手打ちしている。
これを円滑に作成出来たらいいなぁと思ったことがあった。
せっかくHaskellを勉強しているので、これを題材としてプログラムを書いてみる。


このリストを作成するときに、次のような記事番号とタブ、記事タイトルが書かれたテキストファイルを適当に作る。

3	【Haskell】とても簡単なHaskellプログラムについて
8 【Haskell】標準入力(stdin)を読み込むために
36 【Haskell】結構頻繁に使う関数などの話
37 【Haskell】高階関数と型の定義について
489 【Haskell】リストの処理について
509 【Haskell】C言語の構造体のようなものをHaskellで利用する

このリストから上のリンクリストを作成するようなHaskellプログラムを作成する。
とりあえず簡単にするために、標準入力からこのリストを読み込み、標準出力へ出力する。
つまり

mbh.exe < src.txt > href.txt

のように使えるようにする。
まずは次のようにヘッダの部分(水平線の表示)と、リンクのひな形部分を定義しておく。

header = "<hr size=\"1\">category of Haskell:"
hreftp = "http://parabola0.blog86.fc2.com/blog-entry-"

標準入力を読むため、次のように書く。

main = do cs <- getContents
putStrLn header
putStrLn $ unlines $ map getHtml $ lines cs

標準入力から得られる上のテキストファイルのリストを一つずつ処理する。
つまり数値+タブ+タイトルの文字列からHTMLのリンクタグを返す関数getHtmlを作る。

getHtml :: String -> String
getHtml h = let wh = words h
number = head $ wh
title = head $ tail $ wh
in do "<a href=\""
++ hreftp
++ number
++ ".html\"><strong>" ++ title ++ "</strong></a>"

letなど、多少適当に書いていると思う。
(まだここら辺はあまりなれていないのでよく分からない感じもあったり)
これを利用すると次のようなHTMLのソースが出力される。

<hr size="1">category of Haskell:
<a href="http://parabola0.blog86.fc2.com/blog-entry-3.html"><strong>【Haskell】とても簡単なHaskellプログラムについて</strong></a>
<a href="http://parabola0.blog86.fc2.com/blog-entry-8.html"><strong>【Haskell】標準入力(stdin)を読み込むために</strong></a>
<a href="http://parabola0.blog86.fc2.com/blog-entry-36.html"><strong>【Haskell】結構頻繁に使う関数などの話</strong></a>
<a href="http://parabola0.blog86.fc2.com/blog-entry-37.html"><strong>【Haskell】高階関数と型の定義について</strong></a>
<a href="http://parabola0.blog86.fc2.com/blog-entry-489.html"><strong>【Haskell】リストの処理について</strong></a>
<a href="http://parabola0.blog86.fc2.com/blog-entry-509.html"><strong>【Haskell】C言語の構造体のようなものをHaskellで利用する</strong></a>

これをコピペすると、はいブログで使ってるようなリストのできあがり。


category of Haskell:
【Haskell】とても簡単なHaskellプログラムについて
【Haskell】標準入力(stdin)を読み込むために
【Haskell】結構頻繁に使う関数などの話
【Haskell】高階関数と型の定義について
【Haskell】リストの処理について
【Haskell】コマンドライン引数を得る方法
【Haskell】C言語の構造体のようなものをHaskellで利用する

Page Top

訪問者

お引っこし。 http://parabola.sblog.jp/

プロフィール

parabola0

Author:parabola0
Twitter用ですが…。
プロフィール

最新記事
最新コメント
最新トラックバック
カテゴリ
月別アーカイブ
検索フォーム
リンク

このブログをリンクに追加する

QRコード
QRコード
RSSリンクの表示