ふと、手続き型言語だとちょっと大変かな?と思ったプログラム
前回、numberingコマンドを作ってて思ったのですが、手続き型言語はファイルから読む時に1行毎に読むと言うのをコードからも指定している訳ですが、ファイルの中身を全部逆にして、ナンバリングするコマンド(仮にrevnumberingコマンドとします)だと、手続き型言語だとちょっと大変なのかなー・・・と、考えたのですが、どうなんでしょうね?
(所詮はナンバリングコマンドの変形なので、大変って程でも無いけど)
Haskellで書く分にはnumberingコマンドのコード
import System.Environment numbering = unlines.(map (\(x,y) -> show x ++ y)).(zip [1..]).lines main = getArgs >>= \args -> mapM readFile args >>= return.map numbering >>= (mapM_ (\(x,y) -> putStrLn $ x ++ "\n" ++ y)).zip args
に、"return.map reverse >>="を挟んでやるだけなのですが・・・
revnumberingコマンドのコード
import System.Environment numbering = unlines.(map (\(x,y) -> show x ++ y)).(zip [1..]).lines main = getArgs >>= \args -> mapM readFile args >>= return.map reverse >>= return.map numbering >>= (mapM_ (\(x,y) -> putStrLn $ x ++ "\n" ++ y)).zip args
自分が、手続き型言語で書くとしたら、1行毎に読み込んでいるファイルの内容を一旦、文字型の配列なり文字列型なりの変数に格納して、reverseしてから、ナンバリングする感じでしょうか。
Haskellも裏では1行毎に読んでるかもしれませんが、コード上はただファイルの内容が文字列として返ってくるだけなので、こう言う、多少イレギュラーな流れの処理では関数型言語の方が楽なのかなー・・・?とか思ってみたり。
率直なご意見・ご感想・コード(これ重要)。お待ちしております。
ちょっち訂正
こっちでも行けた。
import System.Environment numbering = unlines.(map (\(x,y) -> show x ++ y)).(zip [1..]).lines main = getArgs >>= \args -> mapM readFile args >>= return.map (numbering.reverse) >>= (mapM_ (\(x,y) -> putStrLn $ x ++ "\n" ++ y)).zip args
でも、なぜかnumbering.reverseは関数合成で一つの関数なのに、括弧を外すと上手く動かない不思議。
あ、revnumberingコマンドで、自身のコード(revnumbering.hs)を出力するとこうなります。
revnumbering.hs 1sgra piz.))y ++ "n\" ++ x $ nLrtStup >- )y,x(\( _Mpam( 2 =>> )esrever.gnirebmun( pam.nruter =>> sgra eliFdaer Mpam >- sgra\ =>> sgrAteg = niam 3 4senil.)]..1[ piz(.))y ++ x wohs >- )y,x(\( pam(.senilnu = gnirebmun 5 6tnemnorivnE.metsyS tropmi