トップページtech
1001コメント352KB

関数型プログラミング言語Haskell Part15

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2011/07/09(土) 17:16:54.84
haskell.org
ttp://www.haskell.org/

日本語サイト
ttp://www.sampou.org/cgi-bin/haskell.cgi
ttp://www.shido.info/hs/

過去ログ
関数型プログラミング言語Haskell
Part1 ttp://pc.2ch.net/tech/kako/996/996131288.html
Part2 ttp://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 ttp://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 ttp://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 ttp://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 ttp://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 ttp://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 ttp://pc11.2ch.net/test/read.cgi/tech/1193743693/
Part9 ttp://pc11.2ch.net/test/read.cgi/tech/1211010089/
Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/
Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/
Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/
Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/
Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/
0357デフォルトの名無しさん2011/08/11(木) 10:17:31.99
モナド内包表記って何に使うの?
0358329=343=349=3522011/08/11(木) 14:46:03.01
>>353

>>343の「なんで?」は、>>329でいう「見返り」がなぜ、
>>330の「言語仕様で直接副作用を扱わなくてもよくなるアプリケーションプログラマには何のメリットもない見返り」と断定できるのか、断定できないでしょ、という修辞的疑問。
で、「Parsecをdo記法で書けるのはすげー便利だが」と次の段落で、アプリケーションプログラマにとってメリットのある見返りを例示する、というのが意図した文章構成。

> プログラムのレイアウトのレベルの問題だと思うのだが

そうだね。でも、do記法は実際にアプリケーションプログラマにとって便利だよね。
その便利な記法を、さまざまな型・用途に柔軟に使えるようにしているのが、HaskellのMonadクラス。

>>354
> 演算子を定義しても良い。>>351みたいに。

scala知らないからテキトーだが、>>351の例から推して量るに、例えば 「2001-01-03 10:10」っていうようなフォーマットを解析するのに
 number ~ "-" ~ number ~ "-" ~ number ~ " " ~ number ~ ":" ~ number ^^ { case (y,_,m,_d,_h,_,m) => (y,m,d,h,m) }
って書くのかな。

そういう一回リストや配列で返すことが強制されるよりも
do
 y <- number
 string "-"
 m <- number
 string "-"
 d <- number
 string " "
 h <- number
 string ":"
 m <- number
 return (y,m,d,h,m)
って書くほうが、読みやすく、仕様変更に応じて手を加えるのにミスしにくい、とオレは思う。
しかし、そうは思わないという人が多いのであれば、これ以上はなんとも。
0359デフォルトの名無しさん2011/08/11(木) 15:04:53.22
OCamlのpa_monadは?
perform記法ってdo記法と似てると思うよ

http://www.cas.mcmaster.ca/~carette/pa_monad/
0360デフォルトの名無しさん2011/08/11(木) 16:34:30.62
>>358
何か直交する色んなことを一緒くたに混ぜてる気がするなー。

とりあえず、モナドの利点としてパーサコンビネータを出したのは分かった。(だよね?)
でも、do記法の便利さとモナドの便利さってレイヤーが違うよね?
切り分けないから「?」ってなるんだよ。

>>356が触れているように、Lispのようなメタプログラミングができたり、
>>359が紹介しているような構文拡張ができるプリプロセッサがあれば、
do記法はHaskell以外でも実現できる。

あと余談だけど、do記法については、

ttp://d.hatena.ne.jp/kazu-yamamoto/20101211/1292021817

って意見もある。逆の立場の意見も勿論あるから、これは人によると思う。
自分はdo記法の方が読みやすいと感じる。
0361デフォルトの名無しさん2011/08/11(木) 17:56:17.49
モナドって関数の合成をリーダビリティ高くやる方法見つけましたってだけじゃないの?
0362デフォルトの名無しさん2011/08/11(木) 18:01:51.22
もなどなど〜な〜 ど〜な〜
0363デフォルトの名無しさん2011/08/11(木) 18:21:43.01
>>358

>>329 は「そこで苦しんだだけの見返り」といってる

現時点ではどうしても圏論などとの繋がりが気になって勉強したくなるが、
でも数学が得意でないかぎりかなりの苦闘するよね、というのが「苦しみ」

(もっと深く知りたくて)圏論を勉強しようとして苦闘しても、べつにいいでしょ
苦闘しただけの見返りはあるよ、と言っている

>>329 の言う見返りは、圏論などを学んで「深く関わって」苦闘した上での見返りなんだよ
使い方自体は、do記法を使っていればなんとなく理解できるとも言ってるし

それを受けた >>330>>329 の言いたい事をちゃんと分かった上で、
「圏論などを学んでそこまで深く関わって」得られた見返りは、
アプリケーションプログラマにとっては特にメリットもないよね、と言ってる
使い方を理解すればアプリケーションプログラマには十分だということだろう

で、問題の >>343
それはべつに圏論などを学んで深く関わったからこそ得られた知識
という訳ではないだろう
どちらかと言うと、それは「使い方を理解すれば」の方ではないか?

何による見返りについて話しているのか、が前レスと異なっているように思える
このズレが違和感を覚える
0364デフォルトの名無しさん2011/08/11(木) 18:52:17.75
モナドが関数の合成であるとは限らないでしょう
WriterとかMaybeとか色々あるでしょう
0365デフォルトの名無しさん2011/08/11(木) 19:33:29.84
あ、ちなみにScalaでもこんな風に書けるよ
for {
 y <- number
 _ <- string("-")
 m <- number
 _ <- string("-")
 d <- number
 _ <- string(" ")
 h <- number
 _ <- string(":")
 m <- number
} yield (y,m,d,h,m)
0366デフォルトの名無しさん2011/08/11(木) 21:07:46.63
scalaのforがhaskellのdoに見えてきた、、、
0367デフォルトの名無しさん2011/08/11(木) 21:15:45.91
ScalaはHaskellだったのか!
0368デフォルトの名無しさん2011/08/12(金) 02:47:52.52
http://www.google.com/m?hl=ja&gl=jp&
q=%E3%83%A2%E3%83%8A%E3%83%89%E3%81%AF%E8%B1%A1%E3%81%A0
PART2の最後にhaskellのdoとscalaのforの対比があるよ
0369デフォルトの名無しさん2011/08/12(金) 02:50:25.65
http://dl.dropbox.com/u/261418/Monads_are_Elephants/part2-ja.html#id5
0370デフォルトの名無しさん2011/08/16(火) 20:37:25.69
ghc 7.2が出たみたいね。
http://ja.wikipedia.org/wiki/GHC
0371デフォルトの名無しさん2011/08/16(火) 21:15:59.99
http://www.haskell.org/ghc/

きとったか
0372デフォルトの名無しさん2011/08/16(火) 22:21:34.71
GHC 7.4 won't have top-level MonoPatBinds anymore!
http://hackage.haskell.org/trac/ghc/ticket/2357
0373デフォルトの名無しさん2011/08/17(水) 09:29:16.82
Scala is NOT Haskell but a child of Haskell.
0374デフォルトの名無しさん2011/08/17(水) 16:08:28.02
7.2 のghciに新たにできた? :set +m はよさそうね。replの
使い勝手が少し良くなりそう。
0375デフォルトの名無しさん2011/08/18(木) 11:47:29.02
プログラミングHaskellのp.41に
add x y = x + y

add = \x -> (\y -> x+y)
は同等と書かれているのですが、
前者は add :: Num a => a -> a -> a
後者は add :: Integer -> Integer -> Integer
になり、後者は小数の加算ができません。
どこからIntegerだと型推論されるのでしょうか?
GHC7.0.3もHugsも同じようです。
0376デフォルトの名無しさん2011/08/18(木) 13:05:53.11
Monomorphism restriction
0377デフォルトの名無しさん2011/08/18(木) 13:08:39.12
defaultingという仕組みによるものです。
http://www.sampou.org/haskell/report-revised-j/decls.html#sect4.3.4

上のレポートにあるように、add :: Num a => a -> a -> aと型シグニチャを書くか
defaultingを止めるためにモジュールの先頭で

{-# LANGUAGE NoMonomorphismRestriction #-}
default ()

としてやると意図通りの型になります。
0378デフォルトの名無しさん2011/08/18(木) 13:09:40.86
>>375
ほんとだ、、、
型かけばちゃんとNumになるのに、、、
0379デフォルトの名無しさん2011/08/18(木) 14:52:23.51
>>376,>>377
ありがとうございます。

4.5.5にそのままの例が載っていますね。
今の自分にはかなり難しいので、
もうちょっと理解が進んでからよく読み直してみたいと思います。

ところで、
{-# LANGUAGE NoMonomorphismRestriction #-}
default ()
をすると、p.18の練習問題にある
n = a `div` length xs
where
a = 10
xs = [1,2,3,4,5]
がエラーになってしまいます。
型推論に頼るのはなかなか難しいものですね。
0380デフォルトの名無しさん2011/08/18(木) 15:08:33.58
> 379

最小の再現コードは

n = length [1,2,3,4,5]

で、これもさっきのレポートのlet x = read "..." in show xの例と同じです。
defaultingをoffにしているので、[1,2,3,4,5] :: Num a => [a]となり、
length :: [a] -> Intなので、length [1,2,3,4,5] :: Num a => Intと推論されるので
これは曖昧な型であると型検査で弾かれます。

解決策は型エラーのメッセージにも出ているように、型シグニチャを書いてやれば
OKです。

n = length ([1,2,3,4,5] :: [Integer])
0381デフォルトの名無しさん2011/08/18(木) 15:12:32.55
基本的にはdefaultingが云々とか気にせず、自分の想定している型を
書くようにするのが嵌らないし、良いお作法だと思いますよ。
0382デフォルトの名無しさん2011/08/18(木) 16:09:06.94
何度もありがとうございます。
型シグネチャをつける有用性がよくわかります。

型が曖昧というのは、length が使われる環境から 1 とか 2 の型が確定できな
いということでしょうか。
で、数値に限っては、こういう場合にデフォルトがとれるようにしてあると。

ためしに、
s = show 1
をやってみるとエラーになるのも、たぶん同じ理由ですね。

ありがとうございました。
0383デフォルトの名無しさん2011/08/18(木) 22:22:49.57
整数を扱うとき、IntにするかIntegerにするかいつも迷う。
(大きさはIntで十分。効率も問わない場合)

どちらが基本(多くのライブラリ関数が想定してる)のだろう?
0384デフォルトの名無しさん2011/08/18(木) 22:55:41.28
余程大きな数を扱う可能性が捨てきれないとき以外は普通は Int じゃないか
いくら Integer の処理速度が上がってきているとはいえ、
メモリ量も処理速度も Int の方がまだまだ圧倒的に効率いいよね

Hoogle でざっと見てみたところ、日付や時間を扱う関数では Integer をよく使うね
それほど真面目に調べてはいないけど、それくらいしか見当たらないような気がする
0385デフォルトの名無しさん2011/08/19(金) 11:07:25.10
これだけ型安全に拘った型システムで、
実行効率を犠牲にしてでも遅延評価による計算可能性に拘った言語で、
わざわざ有限桁の整数型つかうのかよw
0386デフォルトの名無しさん2011/08/19(金) 12:38:39.50
>>385
そのようなしっかりした根拠とポリシーを持っているのなら、
あなたは無限桁の整数型を使えばいいだけの話だよ

人の意見に無理に従う必要は無い
0387デフォルトの名無しさん2011/08/19(金) 14:30:19.72
まだ、発展途上なんですよ
0388Perl忍者2011/08/19(金) 15:49:10.04
お前らまだこんな無駄なことやってんのか
かわいそう
















哀れ
0389デフォルトの名無しさん2011/08/19(金) 15:52:45.11
>>387
発展途上ったって、bignumぐらい有限桁とシームレスに使わせろよ。
LISP以下だぞwww
0390デフォルトの名無しさん2011/08/19(金) 17:03:02.57
LISP使ってろって
0391デフォルトの名無しさん2011/08/19(金) 19:11:23.21
実際Integerは遅いんだから仕方ない
Integerを多用してるtimeライブラリがボトルネックになることがあるくらい
0392デフォルトの名無しさん2011/08/19(金) 19:47:12.79
なんで遅いの?
他の言語だと同じような遅さはあるの?
それともHaskellの実装が腐ってるの?
0393デフォルトの名無しさん2011/08/19(金) 19:47:23.40
LISP使ってろって
0394デフォルトの名無しさん2011/08/19(金) 20:50:19.60
なんで、ってBigNumだからとしか言いようがない

他の言語でもBigNumなら似たようなもん
0395デフォルトの名無しさん2011/08/19(金) 21:29:37.20
Int作ったやつ頭おかしいだろ
まともに整数を実装できてないデータ型なんだからUnsafeIntにすべき
危険なのにもかかわらずunsafeが付いていないのはおかしい
headやlastと同じくらい消えるべき存在
0396デフォルトの名無しさん2011/08/19(金) 21:48:21.28
>>394
んなこたねえよ。
今時の処理系なら小さい数字のパフォーマンスはほとんど落ちない。
遅延評価のコストに比べりゃ誤差の範囲内だ。
0397デフォルトの名無しさん2011/08/19(金) 22:08:29.77
と、数字も出さずに語るのが関数型スレの特徴です。
0398デフォルトの名無しさん2011/08/19(金) 22:14:39.36
自分で比較実験すれば容易に分かることをいちいち提示しないのが関数型スレ

そんな簡単なことも面倒がってやらない >>397 のような奴は消えろ
0399デフォルトの名無しさん2011/08/19(金) 22:34:54.53
いやどう考えても>>396は間違ってる
遅延評価のコストは小手先の最適化でかなり回避できるけど、
Integerを使ってしまったら局所的にいじってもどうにもならない
0400デフォルトの名無しさん2011/08/19(金) 22:41:33.26
fixnumの範囲の値はfixnumで扱って、bignumの範囲の値はbignumで扱い、
それをひとつの型で隠蔽するっていう、最近ではごく普通に使われる手法の話じゃないの?
0401デフォルトの名無しさん2011/08/19(金) 22:46:53.72
>>400
それをやってるのがInteger
0402デフォルトの名無しさん2011/08/19(金) 22:57:46.47
じゃあ、それでも遅いってことは、>>392の言う所の後者ということで、
プリミティブなインストラクションを生成しないとかで、GHCの最適化性能が良くないってこと?

まさか多倍長整数の計算をしてて遅いとか言ってることはないと思うけど、どうなんだろう。
0403デフォルトの名無しさん2011/08/19(金) 23:01:12.18
間接参照を剥がすのが遅い
0404デフォルトの名無しさん2011/08/19(金) 23:07:13.43
なるほど。それじゃあ、現状で複数の型があるのは現実的な選択なわけだ。
個人的には>>395の言うようにUnsafeIntとかの方が良いと思うけど、互換性の問題があるだろうし。
教えてくれてありがとう。
0405デフォルトの名無しさん2011/08/19(金) 23:15:32.47
>>395
> まともに整数を実装できてないデータ型なんだから「Unsafe」Intにすべき

Haskell における Unsafe というのは、そういう意味なの?
0406デフォルトの名無しさん2011/08/19(金) 23:16:44.90
理想的にはlengthとか!!とかもIntegerベースにしたいところだろうが、
まだきついか。
0407デフォルトの名無しさん2011/08/19(金) 23:21:25.14
>>406
冗談だろ
0408デフォルトの名無しさん2011/08/19(金) 23:24:38.85
>>406
Data.List.genericLength
Data.List.genericIndex
理想主義者のためだけに用意された関数だ、受け取れ
0409デフォルトの名無しさん2011/08/19(金) 23:25:32.77
Integerにしてもコンパイルすると32bitまたは64bit値として扱われるとかそういうのならおk
むしろIntegerどころか0とSuccが定義されてるなんらかのクラスのインスタンスならなんでもおkみたいなぐらい一般化してくrくr
どうせ最終的にAgdaとHaskellはシンクロする運命なんだし
0410デフォルトの名無しさん2011/08/19(金) 23:28:47.26
>>409
> Integerにしてもコンパイルすると32bitまたは64bit値として扱われるとかそういうのならおk

その Integer 型の値が32bitまたは64bit値に収まる範囲しか使っていないのかどうか、
コンパイル時にどうやって調べるの?
0411デフォルトの名無しさん2011/08/19(金) 23:30:20.00
正しさの検証をしやすいのは圧倒的にIntegerだねえ
0412デフォルトの名無しさん2011/08/19(金) 23:34:21.47
Agdaとシンクロして自動証明のテクニックでどうにかするようになればいい
0413デフォルトの名無しさん2011/08/20(土) 00:50:24.23
ルビを最適化した天才ティーンネイジャー呼んで最適化してもらえよ
0414デフォルトの名無しさん2011/08/20(土) 08:46:38.54
いくら i++ しても 0x7fffffff に達することはないと仮定したお気楽コード書いてる奴なんだろうな
0415デフォルトの名無しさん2011/08/20(土) 08:54:19.63
length :: forall a n. Integral n => [a] -> n
let unmo = length xs in
(hoge :: Int) + unmo
こんな感じで一般化されたものを使用される部分で明示的に効率重視の型に制限してやるとコンパイル時に最適化可能だから
その辺のアプローチでいくのが現実的かな?common lispのtheみたいなものか
でも行き着く先は依存型を使って、コンパイラが自動n∈[minBound (a:=Int), maxBound(a:=Int)]的な命題の証明を試みて
それが通ればIntに具体化するみたいな機構になると思う
0416デフォルトの名無しさん2011/08/20(土) 11:11:14.23
>>415
前者の最適化は既に実装されてる
http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.4.0.0/src/Data-List.html#genericLength
0417デフォルトの名無しさん2011/08/20(土) 16:32:32.45
>>415
それを証明出来るケースなんて、そう多くないぞ。
0418デフォルトの名無しさん2011/08/20(土) 16:50:59.40
win版のhaskellってメモリ簡約使ってないの?
linux x86-64版だと時間かかる処理でも一回実行すれば、メモリ簡約が効いて速くなるのに、winだと速くならん
同じ処理時間が掛かってる
0419デフォルトの名無しさん2011/08/20(土) 17:25:34.61
>>418
Linuxでメモリ簡約が効いていると判断した手段を用いて、Windowsでメモリ簡約が効いているかどうかを確かめてみる
0420デフォルトの名無しさん2011/08/20(土) 17:27:45.63
>>419
いや、だから使って見て明らかに効いてないんよ
0421デフォルトの名無しさん2011/08/20(土) 18:46:44.53
>>418
メモリ簡約ってのは初めて聞いた言葉だけど、メモ化のこと?

問題をもう少し絞り込みたいんだけど、
とりあえずコア言語レベルではどちらのOSでコンパイルしても同じなの?

それを再現できる可能な限り小さいプログラムのソースは提示できる?

0422デフォルトの名無しさん2011/08/20(土) 18:51:43.25
>>418
あと、+RTS -p オプションで出力した *.prof ファイルで、
問題の関数の entries や %time はどちらのOSでも同じなの?

他に *.prof ファイルで、Linux と Windows で違いは出てる?
0423デフォルトの名無しさん2011/08/20(土) 18:52:33.82
>>421
メモ化の事です

sum関数に時間が掛かってると感じる程度の、でかいリスト入れればおk
もう一度、同じ引数渡したら、普通はメモリ内を検索して結果を返すだけの時間しか掛からない
0424デフォルトの名無しさん2011/08/20(土) 19:17:41.45
>>423
申し訳ないが、具体的にあなたが試したコードを見せてくれないだろうか
原因が他に隠れている事は一切無いとは言い切れないし、
一字一句同一のコードで試したい

あと大事なことを忘れていた
各OSのバージョン、およびGHCのバージョンも教えてほしい
0425デフォルトの名無しさん2011/08/20(土) 19:22:31.80
この具体的なコードの出さなさ具合と環境を言わないのと根拠があいまいな点から考えると
問題の切り分けにすら不慣れなレベルで
8割くらい他の原因orただの勘違いと予想しておくよ
0426デフォルトの名無しさん2011/08/20(土) 19:28:32.37
そもそも、今の GHC って自動で「引数 <-> 戻り値」のメモ化するの?

最新のは知らんが、少し前までは自動ではメモ化しない方針だったはずだが
0427デフォルトの名無しさん2011/08/20(土) 19:33:03.81
>>424
ghci上だし、単純極まりないですよ?

sum [1..10000000]

以上ですw
実行ファイルで試すなら、上記コードを繰り返す実行ファイルを作るとかでしょうか。。。

環境は
win7 ghc 7.2.1
ubuntu 11.04 ghc 6.12.3

cpu Core i5 memory 2GB(デュアルブートなので、ハードスペックは同一です)

0428デフォルトの名無しさん2011/08/20(土) 19:34:35.34
あ、ubuntuは64bit版です
多分コンパイラも64bitかと
0429デフォルトの名無しさん2011/08/20(土) 19:45:27.10
以上ですw じゃねぇよ、コピペで完全に再現できるコードを示せ
GHC のバージョンを揃えて実験しろ
+RTS -p オプションで出力したプロファイラを比べろ

何度も言わせるな


これからこちらで ubuntu のデュアルブートの環境を作りますから、
それまでに完全なソースコードと、プロファイラの実験をお願いします
0430デフォルトの名無しさん2011/08/20(土) 20:23:01.74
環境間でのオブジェクトコードの比較するのにバージョンすら揃えないってのはどうなのよ……。
0431デフォルトの名無しさん2011/08/20(土) 21:13:03.95
それghciで1.5Gも食いやがる。^^;
0432デフォルトの名無しさん2011/08/20(土) 21:31:25.40
一応実行ファイルになるコードは書けたんですが、+RTS -pオプション付けるとエラーが出るんですが。。。
(-pを消すと一応エラーは出ない)

プロファイルとかとった事無いので、分かりません。。。

元が単純なので、一行コードです

main = putStr ((show. (( sum [1..100000]) + ( sum[1..100000]))) ++ "\n")

バージョンは最近までhaskellPratformで同じバージョンにしてたのですが、ghcの最新バージョンをwinの方に入れたので。。。
(linuxは初心者なのでcabからしか入れられないです)
0433デフォルトの名無しさん2011/08/20(土) 21:32:33.92
>>431
プロファイルとか分からないんで、体感出来るくらいの差が出るようにしたら、そんな事になりました
0434デフォルトの名無しさん2011/08/21(日) 09:37:09.98
諸君、良い朝だ
議論したまえ
0435デフォルトの名無しさん2011/08/21(日) 09:58:37.58
>>434
>>432のプロファイルの取り方教えて下さい
0436デフォルトの名無しさん2011/08/21(日) 10:15:45.02
なんでドキュメント読まないの?
なんでググらないの?
バカなの? 死ぬの?
0437デフォルトの名無しさん2011/08/21(日) 10:23:04.78
>>436
realWorldHasell読みながらやってみたけど、上手くいかない。。。
0438デフォルトの名無しさん2011/08/21(日) 10:38:52.07
書籍は情報が古くなる場合もあるから、公式のドキュメント読んだ方が良いよ。
あと、上手くいかないって、どこが上手くいってないのか教えてくれないと、
エスパーじゃないと教えられんと思うよ。エラーメッセージくらい出そうぜ。
0439デフォルトの名無しさん2011/08/21(日) 10:49:29.33
>>438
ありがとう
もうちょい頑張ってみます

初めてプロファイルなるもの出そうとしてるから、ファイルが生成されるのか、何か表示されるのかすら分かってない

RTSとは何をするのかから、調べてみます

エラーは、RTSへのオプションが違うと言われてるんで、

プログラム名 +RTS -p -RTS

の-pに何か追加で書くのが有るんじゃ無いかと推測してるんですが。。。
0440デフォルトの名無しさん2011/08/21(日) 12:12:34.44
+RTS -s -RTSなら通ったので、一応linuxとwinでファイルに保存してzipに固めました。
URL長いですが・・・

https://skydrive.live.com/?sc=documents&cid=c4a8aea1fe363811#cid=C4A8AEA1FE363811&id=C4A8AEA1FE363811%21767&sc=documents
0441デフォルトの名無しさん2011/08/21(日) 12:59:23.35
ghc-7.0.3では
コンパイルする時に-prof -auto-all -rtsopts付けて
実行時に+RTS -p -RTSだけでいけましたお
0442デフォルトの名無しさん2011/08/21(日) 13:06:09.77
>>432
だからな、コードは書き写しじゃなくてコピペしてくれ
show の後にドットがあっては型エラーだろ?

次のコードで試してみてくれないか?

main = putStr (show ({-# SCC "sum1" #-}sum [1..100000] + {-# SCC "sum2" #-}sum [1..100000]) ++ "\n")

コンパイル時はオプション 「-O2 -rtsopts -prof」 を付けてくれ
実行時はオプション 「+RTS -p」 を付けてくれ

そうすると、*.prof ファイルができる
ただのテキストファイルだから適当なエディタで開いてくれ

>>443 へ続く
0443デフォルトの名無しさん2011/08/21(日) 13:06:33.26
>>442 からの続き

下の方に列名が COST CENTRE や MODULE などになっている表がある
COST CENTRE の sum1 や sum2 の行の右の方を見てくれ

列名 entries の所が、この関数(sum1 や sum2 は式)に処理が移った回数だ
その右隣の individual %time が処理全体にかかった時間に対する
この関数(式)に費やしたトータルの時間の割合だ
100 と書かれていれば、ほぼ 100% この処理に費やしているという意味

その右側の individual %alloc が処理全体に費やしたメモリ量に対する
この関数(式)に費やしたトータルのメモリ量の割合だ

意味は予想付くと思うが、上記コードの sum1 と sum2 のコメント欄は、
すぐ右隣の式のコストを計測してくれというコンパイラ指示だ

うちの Windows7、GHC 7.0.3 でコンパイルしたところ、
sum1 は 100% の時間 50% のメモリ量、sum2 は 0% の時間 50% のメモリ量だった
つまり、sum2 の式は端折られている(sum1 の値が使い回されている)わけだ
(ちなみに、CPU : core2 duo P8600 2.40GHz で一瞬だった)

とりあえず結果のみだ、こうなる理由はこれから検証してみる
0444デフォルトの名無しさん2011/08/21(日) 13:08:05.01
>>441
コンパイル時に-rtsoptsしか付けてませんでした。。。
再度挑戦して来ます

本当にありがとうございます
0445デフォルトの名無しさん2011/08/21(日) 13:12:50.71
>>442
了解です
04464432011/08/21(日) 13:24:29.97
すまん、うちの Windows7、GHC 7.0.3 の結果が違ってた
ソースファイルを保存しないで、間違ってた古いファイルでコンパイルしてた

正しくは、sum1 も sum2 もほぼ 50% の処理時間で、50% のメモリ量だった

つまり、どちらの sum もしっかり同じ総和計算をしていた
GHC はメモ化は自動では行わないと私は思っていたから、
これは予想通りと言えば予想通り


さきほど ubuntu をやっとインストールできたから、
これからそちらでも試してみる
0447デフォルトの名無しさん2011/08/21(日) 13:55:43.83
>>446
>>432のコードで良いんですよね?
出かけないと行けないので、帰ってからうpしますが、こちらも似たような結果でした
どうも、GCがlinuxの方が速いのが勘違いの原因みたいな。。。
(>>440でうpしたファイルから推測)
04484432011/08/21(日) 14:07:32.68
>>447
> >>432のコードで良いんですよね?
意味はそれいでいいけど、show の右のドットは消せよ

実は私の >>446 の結果は、[1..100000] じゃなくて [1.10000000] でやってみた
2.5秒ほどかかって、先ほども言ったように処理時間&メモリ量ともに半々だった

私も出かけるので、ubuntu での検証は後でしてみる
0449デフォルトの名無しさん2011/08/21(日) 15:20:35.37
ただいまです。
追加でうpしておきました。

https://skydrive.live.com/?cid=C4A8AEA1FE363811&id=C4A8AEA1FE363811%21767&sc=documents#!/?cid=c4a8aea1fe363811&sc=documents&uc=1&id=C4A8AEA1FE363811%21767

sumprog(2)となってる方です。
04504432011/08/21(日) 21:40:15.68
ubuntu 11.04
GHC 7.0.3

で、全く同じプログラムを全く同じように試してみたが、
Windows で試した時と全く同じ結果だったぞ
(こちらでも [1..100000] ではなく [1.10000000] で実験した)

こちらも、sum1 と sum2 でほぼ50%ずつの時間を消費し、
ほぼ50%のメモリ領域を使ってた
Windows で試した時よりも若干遅かったが

GHC のバージョンを揃えて試した結果だ
予想通り、GHC は自動でメモ化は行わないんだよ

そちらの ubuntu で試して明らかに Windows より速いのなら、
メモ化ではない何か別の要因だと思うぞ
0451デフォルトの名無しさん2011/08/21(日) 22:09:54.44
>>450
長々とお手数掛けました
ありがとうございますm(_ _)m

検証に使ったコードだとGCで2倍の速度差が出てるみたいでしたので、最初のやたらメモリ喰うコードだと差が大きくなったのかと予測してます

何なんでしょう。。。
コンパイルでもlinuxの方が速かったし。。。
コンパイラの32bitと64bitの差でしょうかね。。。

ともあれ、ありがとうございました!!

0452デフォルトの名無しさん2011/08/21(日) 23:03:58.49
コンパイルに関してはwindowsネイティブでやるよか
仮想環境上のubuntuでやった方が明らかに速いとかあるからな・・・
0453SCHEME餃子 ◆8X2XSCHEME 2011/08/21(日) 23:39:54.68
グラフ簡約があるんでないの?
それで 50% ずつ消費されるってのは納得いかないな。
04544432011/08/21(日) 23:53:21.45
f x = x + x という関数の f (3 + 1) という適用なら
x がグラフ簡約されて (3 + 1) は1回しか計算されない

でも、f x = g x + g x という関数の f (3 + 1) という適用だと、
たしかに x がグラフ簡約されて (3 + 1) は1回しか計算されないが、
g x つまり g 4 は記述通り2回計算される
g の引数 4 とその結果の値との対応関係がメモ化されないからだ

今回のは後者に相当する
0455デフォルトの名無しさん2011/08/21(日) 23:53:23.43
この例だと二つのグラフが独立に存在するだけで繋がってない
0456デフォルトの名無しさん2011/08/22(月) 02:58:29.15
ま、scalaの方が上だなw
■ このスレッドは過去ログ倉庫に格納されています