他学の「プログラミング序論」の課題をhaskellで解いてみた

三学期に入ってエ学システム学類(略称エシス)の授業を入れてみた。
実を言えば自由単位はすでに余ってるのだが、まぁ、「A率確保のため」と言うことにしておこう。

にしても暇な授業だった。
だったので課題をhaskellってみた。

ポインタのポインタについて。らしい。
課題はなんか引数処理がメインだけど。
まぁargvはchar**だし...。

課題1-1 : 引数を表示する

こんなの

$ ./a.out hoge fuga
hoge
fuga
$


こうなった

import System
main = do args <- getArgs
          sequence $ map putStrLn args

putStrLnをmapしてもdoしないとアクションが起こらない。
ということでsequence。


do使わないとこんな感じ?

import System
main = getArgs >>= sequence . (map putStrLn)

">>="の使い方とかIO周りは苦手だなぁ...。

課題1-2 : 引数の総文字数を表示する

こんなの

$ ./a.out a ab abc
6
$


こうなった

import System
main = do args <- getArgs
          print $ length $ concat args

課題見てまず思い浮かんだのが、Cでなくhaskellというね。
なんというかhaskellが完全に最近のマイブームになってる
Cで書くよりconcatしてlengthした方が楽。とか思ってしまう。
ちなみにC言語のargvは[0]が実行ファイル名だからtailが必要。


同様にdo無しで。

import System
main = getArgs >>= print . length . concat

課題1-3 : 引数のうちオプション('-'で始まるもの)の個数をそれぞれ数える

こんなの

$ ./a.out -ivh -w -w hoge -vABC
A:1
B:1
C:1
h:1
i:1
v:2
w:2
$

オプションは結合できるという条件らしい。
つまり"-hoge" = "-h -o -g -e"


少し悩んだがこうなった

import System
import List
main :: IO ()
main = do args <- getArgs
          printTuple $ countToTuple $ sort $ concat $ map optionFilter args
		  where optionFilter ('-':xs) = xs
		        optionFilter _ = []

countToTuple :: (Eq a) => [a] -> [(a,Int)]
countToTuple [] = []
countToTuple xs@(x:_) = (x,length ys) : countToTuple zs
		where (ys,zs) = partition (== x) xs

printTuple :: [(Char,Int)] -> IO ()
printTuple [] = return ()
printTuple ((x,y):xys) = do putStr (x:":")
                             print y
			     printTuple xys

ちと汚いが勘弁です。
countToTuple:: (Eq a) => [a] -> [(a,Int)]はPreludeとかList.にありそうな気がするんだがなぁ...
まぁ、命名センスが無いのは置いておいてくださいな。


とりあえず流れとしては引数のうち'-'で始まるやつは'-'抜いて、それ以外は完全無視して、concat。
で、そいつを相手にそれぞれの文字を数える、と言った感じ。


doなしはmainのとこを"getArgs >>="にしてs/\$/./gすればいいので割愛。


リスト相手だとhaskell「まじやべぇ」くらいに使える。
まじやべぇ。

#あは。タプルのスペル間違えてたw
#訂正 2007/12/10