2008年04月29日

「C#プログラミングレッスン」 C#3.0文法編

   このエントリーをはてなブックマークに追加 Clip to Evernote
Gushwell's C# Programing Page --「窓際プログラマーの独り言」別館で、メールマガジン『C#プログラミングレッスン』のバックナンバー「C#3.0文法編」をダウンロードできるようにしました。

C#3.0で追加された、var変数、オブジェクト初期化子、匿名クラス、拡張メソッド、ラムダ式などの説明をしています。

現在は、LINQ to Objects について連載中です。
  

Posted by gushwell at 15:39Comments(0)TrackBack(0)

2008年04月27日

C#プログラミングレッスン・LINQ to Objects

   このエントリーをはてなブックマークに追加 Clip to Evernote
メルマガの連載を休んでいる間に、LINQ to Objectsの記事を書き溜めておこうと思ったのですが、Haskellに夢中になっていて、書き溜めることができませんでした。orz

でも予定通り、今週メルマガの発行を再開しようと思います。

ご期待ください。
連載を休んでいる間も読者数が50人近くも増えており、嬉しいかぎりです。





  
Posted by gushwell at 11:14Comments(0)TrackBack(0)

2008年04月26日

[Haskell] 型チェックは意外と厳しい

   このエントリーをはてなブックマークに追加 Clip to Evernote
getAverage :: (Fractional a) [a] -> a
getAverage xs = div (sum xs) (length xs)

という関数を書いてみた。

最初の行では、aという型がFractionalクラスに属していることを示している。
Fractionalクラスは、小数点を扱える数値型。

でもなぜかコンパイルエラーになった。なんか型が一致しないようだ。
なぜ?

sum xs / (length xs)

って書いてもだめ。

調べてみると、この場合割り算の分子は、Fractionalである必要があるので、
fromIntegral で型変換をする必要がある。

getAverage xs = sum xs / fromIntegral (length xs)

C#のキャストのようなものかな。

Haskellの型チェックって見た目以上に厳しいようだ。  
Posted by gushwell at 21:44Comments(0)TrackBack(0)

2008年04月23日

[Haskell] foldl関数の動き

   このエントリーをはてなブックマークに追加 Clip to Evernote
Haskellのmaximum関数は,
maximum, minimum :: (Ord a) => [a] -> a
maximum [] = error "Prelude.maximum: empty list"
maximum xs = foldl1 max xs

という定義らしい。
ここで出てきた foldl1についても調べてみる。
foldl1の定義は、
foldl1           :: (a -> a -> a) -> [a] -> a
foldl1 f (x:xs) = foldl f x xs
foldl1 _ [] = error "Prelude.foldl1: empty list"
foldl            :: (a -> b -> a) -> a -> [b] -> a
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs

だ。

重要なのは、
 foldl f z (x:xs) =  foldl f (f z x) xs

の部分。
 foldl func z (x:xs)

という関数呼び出しのコードだと、
 func z x

の値を新たな z ととし、xs を新たな第3引数のリストとし、再帰的にfoldlを呼びだすというものだ。
こうすることで、f の結果を保持しながら、リストを順に処理できることになる。

具体的に見てみよう。たぶん以下のように推移するんだと思う。
maximum [1,5,3,4]
-> foldl1 max [1,5,3,4]
-> foldl max 0 [1,5,3,4]
-> foldl max (max 0 1) [5,3,4]
-> foldl max 1 [5,3,4]
-> foldl max (max 1 5) [3,4]
-> foldl max 5 [3,4]
-> foldl max (max 5 4) [4]
-> foldl max 5 [4]
-> foldl max (max 5 4) []
-> foldl max 5 []
-> 5

僕にはとても思いつきません。

  
Posted by gushwell at 23:27Comments(0)TrackBack(0)

2008年04月22日

[Haskell] 指定した長さより長い文字列を取り出す

   このエントリーをはてなブックマークに追加 Clip to Evernote
標準入力から指定した長さよりも長い行だけを
標準出力へ複写するプログラムを書け。
 
main = do {
cs <- getContents;
args <- getArgs;
putStrLn $ unlines $ selectlines (read $ head args) $ lines cs
}

selectlines :: Int -> [String] -> [String]
selectlines n list = filter (\s -> (length s) >= n) list


このコードでのポイントは filter関数かな。
関数(ここではラムダ式)で与えた条件に一致するものだけを返す関数。
この場合は、文字列のリストから、長さが n 以上の文字列だけを
抜き出すというもの。

map と filterがあれば、随分といろんなことが出来そう。

C#のLINQではSelectとWhereに対応しているような感じですね。

main の do 記法は、いつもとちょっと変えて、{ } を使ってC#風に
書いてみた。
僕には、この方がしっくりきますね。
{ }を使わなければ、

main = do cs <- getContents
args <- getArgs
putStrLn $ unlines $ selectlines (read $ head args) $ lines cs

  
Posted by gushwell at 22:51Comments(0)TrackBack(0)

2008年04月21日

[Haskell] 月の日数を求める

   このエントリーをはてなブックマークに追加 Clip to Evernote
指定した月の日数を求める関数を作れ。
ただし、うるう年は考慮しなくてもよい。

やりたいことは実に単純なんだけど、リストのn番目を求めるのってどうやるんだろうか?
調べたら !! 演算子があるということがわかった。

なるほど、それならば、

daysOfMonth :: Int -> Int
daysOfMonth n = days !! (n-1)

days :: [Int]
days = [31, 28, 31, 30, 31, 30, 31,31, 30, 31, 30, 31]

でOKかな。

自分で、!! 演算子と同じことをやる関数を作るとするとどうやるのかも考えてみた。

valueAt :: Int -> [Int] -> Int
valueAt n (x:xs)
| n == 0 = x
| otherwise = valueAt (n-1) xs

とこんな感じか。
随分とHaskellの再帰処理にも慣れてきたようだ。

ところで、今気がついたんだけど、Haskellで例外処理って
どう書くのかな?
これこは、明日以降の課題ですね。
  
Posted by gushwell at 22:59Comments(0)TrackBack(0)

2008年04月20日

[Haskell] maximumを使わずに最大値を求める

   このエントリーをはてなブックマークに追加 Clip to Evernote
標準関数 max, maximum を使わずに、最大値を求める関数を書け。

最初に書いたコードはこれ。

maxnum :: [Integer] -> Integer
maxnum [a] = a
maxnum (x:xs)
| x > maxnum xs = x
| otherwise = maxnum xs

ガードを使って書いてみた。
2回同じ maxnum xs が出てどうなんだろう?って思ったが、動くことには動いた。でも、ものすごく遅い。

次に書いたのがこちら。

maxnum :: [Integer] -> Integer
maxnum (x:xs) = maxnum_ x xs
 
maxnum_ :: Integer -> [Integer] -> Integer
maxnum_ n [] = n
maxnum_ n (x:xs) = maxnum_ (maxn n x) xs
 
maxn :: Integer -> Integer -> Integer
maxn a b = if a > b then a else b

これならば、速度的には問題ないようだ。
でも、意外と手こずった。

先頭の要素を2つ取り出すのに、2段階に関数を定義しなければならないのが厄介だが、これしかやり方が思いつかない。
foldl系の関数を使えばもっと簡単になるが、foldl系の関数も中身は同じようなことをやっているので、本質的には変わらない。
  
Posted by gushwell at 10:55Comments(0)TrackBack(0)

2008年04月18日

MSDN Magazine Topics

   このエントリーをはてなブックマークに追加 Clip to Evernote
MSDN Magazine Topics

いつから、こんなページがあったんだろう?
最近でしょうか?

カテゴリ別に記事の一覧が出てくるのはとてもありがたいです。
  
Posted by gushwell at 20:54Comments(0)TrackBack(0)