2005/07/29
2005/07/28
いまさら気が付いたしょうもないこと。Scheme と Haskell では fold の動作が違うんですね……
どちらもこんな風に書くわけだけど(Haskellの場合は foldl)、
これが Scheme では
と評価されるのに対し、Haskell では
とみなされる。
「種とリストの要素のどちらを先に proc に渡すか」が正反対なので、除算みたいな可逆でない演算の場合に思い悩む。
この例では Haskell のほうが感覚にマッチするなあ。Scheme で Haskell と同じことがしたい場合には無名関数を使うしかないのかしらん。
なんでこんなことが気になったかというと、情報処理学会誌6月号の Haskell の数当てゲームの記事に、0~9 の自然数からなるリストを各数字が各桁に対応する1つの自然数に移す関数 pack: (a b c ..) → abc.. が foldl で実装されていたから。こんなやつ。
上記のような理由で、これをそのまま Scheme に置き換えても期待した結果は得られない。
lambda 内の x と y を逆にすればいいだけなんだけどさ。
どちらもこんな風に書くわけだけど(Haskellの場合は foldl)、
fold proc 種 (x_1 x_2 ... x_n)
これが Scheme では
proc (x_n ... (proc x_1 種)...)
と評価されるのに対し、Haskell では
proc (...(proc 種 x_1) ... x_n)
とみなされる。
「種とリストの要素のどちらを先に proc に渡すか」が正反対なので、除算みたいな可逆でない演算の場合に思い悩む。
gosh-rl> (fold / 128 '(8 4 2))
0.03125
Hugs.Base> foldl (/) 128 [8,4,2]
2.0
この例では Haskell のほうが感覚にマッチするなあ。Scheme で Haskell と同じことがしたい場合には無名関数を使うしかないのかしらん。
gosh-rl> (fold (lambda (x y) (/ y x)) 128 '(8 4 2))
2
なんでこんなことが気になったかというと、情報処理学会誌6月号の Haskell の数当てゲームの記事に、0~9 の自然数からなるリストを各数字が各桁に対応する1つの自然数に移す関数 pack: (a b c ..) → abc.. が foldl で実装されていたから。こんなやつ。
Hugs.Base> foldl (\ x y -> 10 * x + y) 0 [1,2,3]
123
上記のような理由で、これをそのまま Scheme に置き換えても期待した結果は得られない。
gosh-rl> (fold (lambda (x y) (+ (* 10 x) y)) 0 '(1 2 3))
60
lambda 内の x と y を逆にすればいいだけなんだけどさ。
2005/07/25
2005/07/18
三河島駅前に「若松」という居酒屋がある。毎日のように店の前を通るたび、やきとりと鰻の香にため息をついてきた。なんとなく入る機会もなく、この地に移り住んで5年目、今日初めて店に入ってみた。
店内は休日の18:00すぎだというのにすでに満員状態。かろうじて空いた6人がけの座敷に相席で、念願のやきとりやら鰻やらを注文した。5年間毎日予想してきたとおり、焼がうまい。とりたてて高価な素材をつかっているわけではないのに、焼の上手さで何を頼んでも期待をうらぎらない。しかも安い。
こういう居酒屋が目の前にあるのは素晴らしいことだけど、いかんせん奥様としか利用する機会が持てないのが残念なところ。このあいだも、ちかぢか結婚する友人が東東京に越したいと言ったところ、相手に強行に反対されたらしい。東東京は恐いんだって。むべなるかな。きょうび東京の西のほうが文化的だと思われてるからな。しかし、自分の偏見では、東京は東のほうにこそ文化がかたまっていると思うんだけどなあ。
店内は休日の18:00すぎだというのにすでに満員状態。かろうじて空いた6人がけの座敷に相席で、念願のやきとりやら鰻やらを注文した。5年間毎日予想してきたとおり、焼がうまい。とりたてて高価な素材をつかっているわけではないのに、焼の上手さで何を頼んでも期待をうらぎらない。しかも安い。
こういう居酒屋が目の前にあるのは素晴らしいことだけど、いかんせん奥様としか利用する機会が持てないのが残念なところ。このあいだも、ちかぢか結婚する友人が東東京に越したいと言ったところ、相手に強行に反対されたらしい。東東京は恐いんだって。むべなるかな。きょうび東京の西のほうが文化的だと思われてるからな。しかし、自分の偏見では、東京は東のほうにこそ文化がかたまっていると思うんだけどなあ。
2005/07/15
スターウォーズ エピソード3を見にいったら、コルサント→モンテカルロみたいな連想が働いてしまって、長方形が重なるかどうかを面積の差で解決する問題(参照)ってモンテカルロで解けるじゃん。
これなら長方形を実数で指定できる! ハエを殺すのに焼夷弾を持ち出すみたいな話だってのはわかってますって。
(use gauche.uvector)
(use srfi-27)
(use math.mt-random)
;; make random vector
(define (make-random-vector! n)
(mt-random-fill-f64vector! (make-random-source) (make-f64vector n)))
(define (ith-random randoms i)
(f64vector-ref randoms i))
(define (ith-random-pair randoms i)
(list (ith-random randoms (* 2 i))
(ith-random randoms (+ (* 2 i) 1))))
;; rect as ((x0 x1) (y0 y1))
(define (point-inner-closed? point closed)
(and (< (car closed) point) (< point (cadr closed))))
(define (pair-inner-rects? pair rects) ; not cps !
(let ((rect (car rects)))
(if (null? (cdr rects))
(and (point-inner-closed? (car pair) (car rect))
(point-inner-closed? (cadr pair) (cadr rect)))
(or (pair-inner-rects? pair (list rect))
(pair-inner-rects? pair (cdr rects))))))
;; monte-carlo
;; area as '(rect1 rect2 ...)
(define (monte-carlo area n)
(let ((randoms (make-random-vector! (* 2 (+ n 1)))))
(let f ((i 0))
(if (> i n)
0
(if (pair-inner-rects? (ith-random-pair randoms i) area)
(+ (f (+ i 1)) 1)
(f (+ i 1)))))))
;; main
(define times 10000)
(define rect1 (list (list 0.0 0.2) (list 0.0 0.2)))
(define rect2 (list (list 0.1 0.3) (list 0.1 0.3)))
(define s1 (monte-carlo (list rect1) times))
(define s2 (monte-carlo (list rect2) times))
(define s1-and-s2 (monte-carlo (list rect1 rect2) times))
(display (< s1-and-s2 (+ s1 s2)))
=> #t
これなら長方形を実数で指定できる! ハエを殺すのに焼夷弾を持ち出すみたいな話だってのはわかってますって。
2005/07/07
Haskell と継続について。いただいたコメントによるとモナドで継続を実現できるんですね。Haskellのコードで理解するのはつらいので、ここを読み返してみた。
f: x→y により実行される計算の継続は、f': x→((y→k)→k) となるような f': x→M(y) と見なせる。ここで M はモナド則を満たす。という理解でいいのかな。
にしても、これがHaskellのプログラミングで意味があるのかどうかは、あいかわらずよくわからない。実際に Haskell でプログラミングしているわけじゃないので、わからなくて当然といえばそれまでなんだけど、応用を生み出す妄想力の欠如を我ながら痛感するところ。ところで、あちこちで「Haskell では遅延評価があるから無理に継続引き渡しにしなくてもいい」って言及されているのは、まるで継続と遅延評価とが同じ概念の2つの表現みたいに読めてしまうから、いけないと思う。実際には、評価の順番が問題視されなければ継続引き渡しで処理が最適化されるわけじゃないってだけのことだと思うんだけど、僕のほうが勘違い?
f: x→y により実行される計算の継続は、f': x→((y→k)→k) となるような f': x→M(y) と見なせる。ここで M はモナド則を満たす。という理解でいいのかな。
にしても、これがHaskellのプログラミングで意味があるのかどうかは、あいかわらずよくわからない。実際に Haskell でプログラミングしているわけじゃないので、わからなくて当然といえばそれまでなんだけど、応用を生み出す妄想力の欠如を我ながら痛感するところ。ところで、あちこちで「Haskell では遅延評価があるから無理に継続引き渡しにしなくてもいい」って言及されているのは、まるで継続と遅延評価とが同じ概念の2つの表現みたいに読めてしまうから、いけないと思う。実際には、評価の順番が問題視されなければ継続引き渡しで処理が最適化されるわけじゃないってだけのことだと思うんだけど、僕のほうが勘違い?
2005/07/06
だらだらとWebを見ながら、howm形式でばしばしメモるためのBookmarklet。Firefox1.0.4でのみ動作を確認。改行が便宜的なものであるのはいわずもがな。
本当は、$HOME/howm/以下へ自動的に吐き出したいんだけど、javascriptだけでは無理で、XPCOMを使うしかないっぽい。それにしてもこういうのを書くと生気を吸われるきもち。
javascript:
var pageTitle=document.title;
var pageURL=document.URL;
var userSelection=document.getSelection();
function nomdic(cc){if(cc<10){cc='0'+cc};return cc};
var nowDate=new Date();
var yyyy=nowDate.getFullYear();
var mm=(nowDate.getMonth()+1);
var dd=nowDate.getDate();
var hh=nowDate.getHours();
var min=nowDate.getMinutes();
var ss=nowDate.getSeconds();
var howmName=yyyy+'-'+nomdic(mm)+'-'+nomdic(dd)+'-'+nomdic(hh)+nomdic(min)+nomdic(ss)+'.howm';
var howmDate=yyyy+'-'+nomdic(mm)+'-'+nomdic(dd);
var openWin=window.open('',howmName,'innerWidth=600,innerHeight=400,scrollbars,menubar');
openWin.document.writeln
(howmName + '<br/>= ' + 'URLメモ ' + pageTitle + '<br/>' + '['+howmDate+']' + ' <<< '
+ pageURL + '<br/><br/>' + userSelection); void(openWin.document.close());
本当は、$HOME/howm/以下へ自動的に吐き出したいんだけど、javascriptだけでは無理で、XPCOMを使うしかないっぽい。それにしてもこういうのを書くと生気を吸われるきもち。
登録:
投稿 (Atom)