63bdca94.jpg神保町のマックで昼飯(ハンバーガーx2,ポテトL)をくう。なぜか女子大生っぽいのが大量に席を埋めてる。なんか試験でもやってたのかな。

9c510cba.jpg会場に30分前に行くも、やることなし。WiMAXの入りがよくないので会場のWLANをつかうことに。やっぱレスポンスがいいね! ただこのPCでWLANをつかうと、よくハングアップするのでそれだけが心配だったが最後までちゃんと動いてくれた。

宿題の答あわせ/虎さん

[2011-09-11 13:06]

  • .01のようには書けない。0.01と書かないとだめ。
  • 圧縮率を求める問題は、オーディオのビットレートは圧縮済のものでそれがファイルに書かれてて、ビデオの圧縮率だけを求めるという問題だった。むづい。
  • fromIntegralをつかっている。toが明示されてないところが多相。Haskellは勝手に型変換はしてくれないので面倒かもしれないが、勝手に型変換されてバグるということがなくなる。from〜のほかにto〜もある。
  • xsが長いリストのときに length xs < 4 はもったいないが、どうせreverseしているのでオーダはかわらない。
  • ぜひ cabal install hlint で hlint をいれて、プログラムをチェックしてwarningなしにすべき。
  • whereのところで (x:xs) = ... は括弧はいらないかも。必要ないときもある。むづい。
  • 三角柱の問題は数学的すぎた。解き方は同一平面上にあるかチェックして時計まわりかどうかチェック。
    • 別のやりかた:三角形の部分の法線ベクトルが同じなのをチェックして、あとは各辺が平行なのをチェック。
    • 光学異性体をはじく必要がある。

[2011-09-11 13:41]

5章発表 / @dekosuke

[2011-09-11 13:44]

  • 内包表記はリストからリストへの演算。簡単に書けることがおおい。
  • 再帰よりも内包表記が先にきているのは意外。
    • かずさん→著者Huttonさんが内包表記がだいすきだから。

[2011-09-11 13:58]

6章発表 / @Lost_dog

  • 再帰的定義の例: 私の友達とは := 私または私の友達と話したことがあるひと。
  • productの基底部と再基部の書く順番。よくつかう方を前に書いた方が速くなりそうな気がするが、GHCではよろしくやってくれる。やってくれないこともある。
  • 静的型付けで再帰をつかうと型チェックでよくミスがみつかる。
  • ここでfor文と再帰関数の議論が白熱

[2011-09-11 14:26]

再帰関数補足 / @虎さん

  • n+kパターンがつかえなくなった → ガード n > 0して、otherwise = error "...negative" ではじくよう書く。
  • -Wallでパターン漏れをチェックしてくれる。
  • ガードとかよく成立する条件の方を上にもってくるのが速くなるが、実際にテストしてみるべき。
    • ちなみに虎さんもスピード狂だそう。

[2011-09-11 14:35]

休憩

0c600077.jpgおやつ 神戸屋国産米粉の蒸しパン 宇治抹茶 (255kcal,たん白質3,4g,脂質1.5g,炭水化物57.0g)。あまりふわふわじゃなくてたべごたえがあってよかった。

さっきの発表の続き

[2011-09-11 14:55]

  • 教科書の reverseは遅い実装。
    • ++はリストのコピーが発生する。
  • アキュミュレイターとヘルパー関数をつかう。
  • whereのところにも型宣言がかけるのか。
  • 遅延評価があるので末尾再帰の形になってても、そうならないことが。むずい。とりあえず遅延評価は忘れて..

[2011-09-11 15:03]

  • とらさんはアキュムレータを前(第1引数)に書く派:カリー化がつかえるから。かずさんは後につける派。
  • reverseの例はアキュムレータとしては特別で、ふつうはアキュムレータの型は数値であることがおおい。

[2011-09-11 15:08]

7章発表 / @imagawa_yakata

[2011-09-11 15:09]

グループ演習問題の時間d970ba18.jpg

  • 6人でグループになって演習問題を解く。
  • 問題が難しいので、もくもくとPCにむかってしまう。
  • 3人組くらいにして歩調をあわせていくとかしないと会話が起きないかも..
  • HHKBproをもってきたので、さっそくガチャガチャやる。うるさくてごめん。
  • 疲労困憊でコーラを飲んで休憩。25caba49.jpg

[2011-09-11 17:54]

  • ++は右結合。左結合にしたくて (x++y)++z とかくとxが2回コピーされる。再帰でこの形をつかってるとO(n^2)のオーダになる。

splitAt

自力でこの形にたどりついたのでメモっとく

mysplitAt :: Int -> [a] -> ([a], [a])
mysplitAt n xs | n <= 0 = ([], xs)                      
mysplitAt n [] = ([],[])
mysplitAt n (x:xs) = (x:a, b)
    where
      (a,b) = mysplitAt (n - 1) xs

かなり試行錯誤して、どういう道筋だったかは覚えてないので、いまおもいだしてみるキーポイント:

  • 再帰でもぐっていくときは引数のリストを短かくしていく。引数のnは小さくなっていく。
  • タプルの2番目はn==0になったときのリストをそのままつっこんだらおしまい。
  • (a,b) = f... という風にタプルを受ける。
  • (:)でリストを組むと組んでいく順序と逆順のリストができあがる。 ([]に1:して2:して:3すると[3,2,1]ができる。)
  • 再帰が巻戻ってくるときは引数のリストの逆順で処理される。(f (x:xs) = x `hoge` f xs) の形になってるときに、f [1,2,3]が再帰のスタックからもどってくるときは 右辺の x は 3,2,1 の順になる。
  • なので(:)を再帰の戻りでつかうと、元通りのリストができる。f (x:xs) = x : f xs みたいな感じのやつ。
  • 蓄積変数をつかうと再帰がもぐっていくときに答を作るので、(:)をつかってできあがるリストが逆順になってしまう。++をつかえば別だけども。

質問してみたこと

前から疑問だったガードとかパターンマッチが上から順番というのが、なんでそんな言語仕様になっているのかきいてみた。個人的には条件がオーバーラップしていたら非決定性があってもいいかなという気持ち。

  • 並列化のことは別の枠組みをつかえ
  • 上から順番に書くと記述が簡単になることが多いので。
  • どうせ引数をガードで評価するので関係ないんでは?という意見も。

18:00 終了。懇親会には参加せず(参加したくないわけではないが小遣いが厳しいので)さくっと帰宅。