関数型プログラミング言語Haskell Part15
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2011/07/09(土) 17:16:54.84ttp://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/
0331デフォルトの名無しさん
2011/08/07(日) 16:04:41.480332デフォルトの名無しさん
2011/08/07(日) 16:22:09.65過酷な山登りに喩えられるようなコスト構造よりは、せいぜい大学受験ぐらい
に喩えられるコスト構造にしないと理論的内容も含めた普及はない。
一般的に好まれるのはローコストでハイリターンなものだからね。
0333デフォルトの名無しさん
2011/08/07(日) 16:34:36.90Haskellに(たとえば)MLのレコード型みたいに副作用が使えるものとか、
そういったものが入ることはありえません。
ローコストでハイリターンが好きなら一生PHPでもなんでも使ってるのが
あなたにとって一番の幸せだと思います。多分。
0334デフォルトの名無しさん
2011/08/07(日) 16:37:29.430335デフォルトの名無しさん
2011/08/07(日) 16:52:10.82なので、コストを下げる努力はしない、ということか?
0336デフォルトの名無しさん
2011/08/07(日) 16:55:03.34なんでだろう
0337デフォルトの名無しさん
2011/08/07(日) 17:01:44.98そして誰も使わなくなったとさ
0338デフォルトの名無しさん
2011/08/07(日) 17:09:07.610339LLピザ
2011/08/07(日) 17:13:47.51なのにすごい
お前らの脳みそ=Haskellやってる=すごい
らしいな
だけどバカだな
お前らクズじゃねーかよ
みたらTsuwabukiみたいな、へなちょこばっかりwwwwwwwwww
ゴミクズしかいねえのな
0340デフォルトの名無しさん
2011/08/07(日) 17:14:25.67大学以外で実務で使ってそれで金もらってる人は日本で10人もいないよ
0341デフォルトの名無しさん
2011/08/07(日) 17:20:32.880342デフォルトの名無しさん
2011/08/07(日) 17:48:55.180343デフォルトの名無しさん
2011/08/07(日) 17:50:57.82なんで? Parsecをdo記法で書けるのはすげー便利だが。
もともとWebアプリケーション用としてではなく、不完全なHTMLで書かれていて、かつ仕様も予告なくころころ変わるWebページを定点観測していたときには、すげー便利だったParsec。
Haskellがなければ、あんなこと二度としようとは思わん(それをやるだけで給料もらえるならやるけど)。
0345LLピザ
2011/08/07(日) 17:52:19.13ゴミだったな
まぁ使っていいのはMacだと木下、荻原、Matzあたりだろ
あとはゴミだしなMac使いは
そもそも2chに書き込んでるゴミが使ってもただの個人学習にしかすぎない
0346デフォルトの名無しさん
2011/08/08(月) 14:57:16.67待ちくたびれたー
0347デフォルトの名無しさん
2011/08/09(火) 00:40:23.370348デフォルトの名無しさん
2011/08/09(火) 18:16:00.53普通にコンビネータ使える言語ならどうにでもならねえか、それ?
0349デフォルトの名無しさん
2011/08/09(火) 20:28:00.00実際に手続き型言語でパーサコンビネータを組んでみたけど、Parsecほど使いやすくはならなかったよ。
とくに順次処理をして自分の使いたい型のデータを返すのが、面倒な問題を引き起こす。
例えば、"000 - 000"という文字列を解析して、整数のペアを返したい。
厳密にコンビネータだけ使うなら、例えば seq(seq(number, string(" - ")), number)みたいなやり方をするわけだけど、
これは読みにくいし、せいぜい配列かリストを返すことになって自由な型のデータを返せない
他方、
x = number();
string(" - ")();
y = number();
return (x, y)
みたいにパーサーを実際に副作用させる構文で、自由な型のデータを返すことはできるけど、
最後の()を良く忘れるが必ずしも型検査に引っかからず、バグが見つけにくかった。
まぁ、実際に試してみれば分かると思うけど。
0350デフォルトの名無しさん
2011/08/09(火) 20:29:20.560351デフォルトの名無しさん
2011/08/09(火) 23:31:09.81scalaのコンビネータライブラリなら
number~"-"~number ^^{case (x,_,y) => (x,y)}
だな
0352デフォルトの名無しさん
2011/08/10(水) 00:09:13.74do
x <- number
string " - "
y <- number
return (x, y)
のほうが読みやすくない?
これくらいなら大した差はないかもしれないけど、5〜6要素以上を抽出することになったら、そういう書き方だと面倒くさすぎるだろう。
0353デフォルトの名無しさん
2011/08/10(水) 00:39:36.45> 言語仕様で直接副作用を扱わなくてもよくなる
> アプリケーションプログラマには何のメリットもない見返りな
というのと、
>>343 の
> なんで? Parsecをdo記法で書けるのはすげー便利だが
が、どう繋がっているのか分からない
だれか解説してくれたら助かる
>>343 のは言語仕様で直接副作用を扱うのかどうかというレベルじゃなくて、
プログラムのレイアウトのレベルの問題だと思うのだが
0354デフォルトの名無しさん
2011/08/10(水) 01:45:57.75俺も良く分からない。do記法って構文糖でしょ? 副作用を持つ言語でも同じことできるよね?
>>349もあんまピント合ってない気がする。seqとかは可変長引数とかで見やすくなるし、
演算子を定義しても良い。>>351みたいに。Haskell以外の言語でも問題なくできる部分。
自分で実装した時は、むしろ参照透明性とか遅延評価とかが大きいと思ったけどな。
正格評価だと迂闊にオブジェクトを作ると性能に響くし、かといって副作用で更新すると、
tryとかでオブジェクトをコピーしないといけない場面が出てきて、これまた性能に響く。
効率良く動作するものをHaskellやClean以外で作るのは地味にキツいんじゃないかと感じた。
0355デフォルトの名無しさん
2011/08/10(水) 21:18:56.300356デフォルトの名無しさん
2011/08/10(水) 23:26:58.91do記法のことなら(lispのようなマクロが無い言語では)組み込みじゃないと無理
あとlazyは関係が無い気がする。OCamlでもモナド使うし
0357デフォルトの名無しさん
2011/08/11(木) 10:17:31.990358329=343=349=352
2011/08/11(木) 14:46:03.01>>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.22perform記法ってdo記法と似てると思うよ
http://www.cas.mcmaster.ca/~carette/pa_monad/
0360デフォルトの名無しさん
2011/08/11(木) 16:34:30.62何か直交する色んなことを一緒くたに混ぜてる気がするなー。
とりあえず、モナドの利点としてパーサコンビネータを出したのは分かった。(だよね?)
でも、do記法の便利さとモナドの便利さってレイヤーが違うよね?
切り分けないから「?」ってなるんだよ。
>>356が触れているように、Lispのようなメタプログラミングができたり、
>>359が紹介しているような構文拡張ができるプリプロセッサがあれば、
do記法はHaskell以外でも実現できる。
あと余談だけど、do記法については、
ttp://d.hatena.ne.jp/kazu-yamamoto/20101211/1292021817
って意見もある。逆の立場の意見も勿論あるから、これは人によると思う。
自分はdo記法の方が読みやすいと感じる。
0361デフォルトの名無しさん
2011/08/11(木) 17:56:17.490362デフォルトの名無しさん
2011/08/11(木) 18:01:51.220363デフォルトの名無しさん
2011/08/11(木) 18:21:43.01>>329 は「そこで苦しんだだけの見返り」といってる
現時点ではどうしても圏論などとの繋がりが気になって勉強したくなるが、
でも数学が得意でないかぎりかなりの苦闘するよね、というのが「苦しみ」
(もっと深く知りたくて)圏論を勉強しようとして苦闘しても、べつにいいでしょ
苦闘しただけの見返りはあるよ、と言っている
>>329 の言う見返りは、圏論などを学んで「深く関わって」苦闘した上での見返りなんだよ
使い方自体は、do記法を使っていればなんとなく理解できるとも言ってるし
それを受けた >>330 も >>329 の言いたい事をちゃんと分かった上で、
「圏論などを学んでそこまで深く関わって」得られた見返りは、
アプリケーションプログラマにとっては特にメリットもないよね、と言ってる
使い方を理解すればアプリケーションプログラマには十分だということだろう
で、問題の >>343 だ
それはべつに圏論などを学んで深く関わったからこそ得られた知識
という訳ではないだろう
どちらかと言うと、それは「使い方を理解すれば」の方ではないか?
何による見返りについて話しているのか、が前レスと異なっているように思える
このズレが違和感を覚える
0364デフォルトの名無しさん
2011/08/11(木) 18:52:17.75WriterとかMaybeとか色々あるでしょう
0365デフォルトの名無しさん
2011/08/11(木) 19:33:29.84for {
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.630367デフォルトの名無しさん
2011/08/11(木) 21:15:45.910368デフォルトの名無しさん
2011/08/12(金) 02:47:52.52q=%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.650370デフォルトの名無しさん
2011/08/16(火) 20:37:25.69http://ja.wikipedia.org/wiki/GHC
0371デフォルトの名無しさん
2011/08/16(火) 21:15:59.99きとったか
0372デフォルトの名無しさん
2011/08/16(火) 22:21:34.71http://hackage.haskell.org/trac/ghc/ticket/2357
0373デフォルトの名無しさん
2011/08/17(水) 09:29:16.820374デフォルトの名無しさん
2011/08/17(水) 16:08:28.02使い勝手が少し良くなりそう。
0375デフォルトの名無しさん
2011/08/18(木) 11:47:29.02add 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.110377デフォルトの名無しさん
2011/08/18(木) 13:08:39.12http://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ほんとだ、、、
型かけばちゃんとNumになるのに、、、
0379デフォルトの名無しさん
2011/08/18(木) 14:52:23.51ありがとうございます。
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最小の再現コードは
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書くようにするのが嵌らないし、良いお作法だと思いますよ。
0382デフォルトの名無しさん
2011/08/18(木) 16:09:06.94型シグネチャをつける有用性がよくわかります。
型が曖昧というのは、length が使われる環境から 1 とか 2 の型が確定できな
いということでしょうか。
で、数値に限っては、こういう場合にデフォルトがとれるようにしてあると。
ためしに、
s = show 1
をやってみるとエラーになるのも、たぶん同じ理由ですね。
ありがとうございました。
0383デフォルトの名無しさん
2011/08/18(木) 22:22:49.57(大きさはIntで十分。効率も問わない場合)
どちらが基本(多くのライブラリ関数が想定してる)のだろう?
0384デフォルトの名無しさん
2011/08/18(木) 22:55:41.28いくら Integer の処理速度が上がってきているとはいえ、
メモリ量も処理速度も Int の方がまだまだ圧倒的に効率いいよね
Hoogle でざっと見てみたところ、日付や時間を扱う関数では Integer をよく使うね
それほど真面目に調べてはいないけど、それくらいしか見当たらないような気がする
0385デフォルトの名無しさん
2011/08/19(金) 11:07:25.10実行効率を犠牲にしてでも遅延評価による計算可能性に拘った言語で、
わざわざ有限桁の整数型つかうのかよw
0386デフォルトの名無しさん
2011/08/19(金) 12:38:39.50そのようなしっかりした根拠とポリシーを持っているのなら、
あなたは無限桁の整数型を使えばいいだけの話だよ
人の意見に無理に従う必要は無い
0387デフォルトの名無しさん
2011/08/19(金) 14:30:19.720388Perl忍者
2011/08/19(金) 15:49:10.04かわいそう
哀れ
0389デフォルトの名無しさん
2011/08/19(金) 15:52:45.11発展途上ったって、bignumぐらい有限桁とシームレスに使わせろよ。
LISP以下だぞwww
0390デフォルトの名無しさん
2011/08/19(金) 17:03:02.570391デフォルトの名無しさん
2011/08/19(金) 19:11:23.21Integerを多用してるtimeライブラリがボトルネックになることがあるくらい
0392デフォルトの名無しさん
2011/08/19(金) 19:47:12.79他の言語だと同じような遅さはあるの?
それともHaskellの実装が腐ってるの?
0393デフォルトの名無しさん
2011/08/19(金) 19:47:23.400394デフォルトの名無しさん
2011/08/19(金) 20:50:19.60他の言語でもBigNumなら似たようなもん
0395デフォルトの名無しさん
2011/08/19(金) 21:29:37.20まともに整数を実装できてないデータ型なんだからUnsafeIntにすべき
危険なのにもかかわらずunsafeが付いていないのはおかしい
headやlastと同じくらい消えるべき存在
0396デフォルトの名無しさん
2011/08/19(金) 21:48:21.28んなこたねえよ。
今時の処理系なら小さい数字のパフォーマンスはほとんど落ちない。
遅延評価のコストに比べりゃ誤差の範囲内だ。
0397デフォルトの名無しさん
2011/08/19(金) 22:08:29.770398デフォルトの名無しさん
2011/08/19(金) 22:14:39.36そんな簡単なことも面倒がってやらない >>397 のような奴は消えろ
0399デフォルトの名無しさん
2011/08/19(金) 22:34:54.53遅延評価のコストは小手先の最適化でかなり回避できるけど、
Integerを使ってしまったら局所的にいじってもどうにもならない
0400デフォルトの名無しさん
2011/08/19(金) 22:41:33.26それをひとつの型で隠蔽するっていう、最近ではごく普通に使われる手法の話じゃないの?
0401デフォルトの名無しさん
2011/08/19(金) 22:46:53.72それをやってるのがInteger
0402デフォルトの名無しさん
2011/08/19(金) 22:57:46.47プリミティブなインストラクションを生成しないとかで、GHCの最適化性能が良くないってこと?
まさか多倍長整数の計算をしてて遅いとか言ってることはないと思うけど、どうなんだろう。
0403デフォルトの名無しさん
2011/08/19(金) 23:01:12.180404デフォルトの名無しさん
2011/08/19(金) 23:07:13.43個人的には>>395の言うようにUnsafeIntとかの方が良いと思うけど、互換性の問題があるだろうし。
教えてくれてありがとう。
0405デフォルトの名無しさん
2011/08/19(金) 23:15:32.47> まともに整数を実装できてないデータ型なんだから「Unsafe」Intにすべき
Haskell における Unsafe というのは、そういう意味なの?
0406デフォルトの名無しさん
2011/08/19(金) 23:16:44.90まだきついか。
0407デフォルトの名無しさん
2011/08/19(金) 23:21:25.14冗談だろ
0408デフォルトの名無しさん
2011/08/19(金) 23:24:38.85Data.List.genericLength
Data.List.genericIndex
理想主義者のためだけに用意された関数だ、受け取れ
0409デフォルトの名無しさん
2011/08/19(金) 23:25:32.77むしろIntegerどころか0とSuccが定義されてるなんらかのクラスのインスタンスならなんでもおkみたいなぐらい一般化してくrくr
どうせ最終的にAgdaとHaskellはシンクロする運命なんだし
0410デフォルトの名無しさん
2011/08/19(金) 23:28:47.26> Integerにしてもコンパイルすると32bitまたは64bit値として扱われるとかそういうのならおk
その Integer 型の値が32bitまたは64bit値に収まる範囲しか使っていないのかどうか、
コンパイル時にどうやって調べるの?
0411デフォルトの名無しさん
2011/08/19(金) 23:30:20.000412デフォルトの名無しさん
2011/08/19(金) 23:34:21.470413デフォルトの名無しさん
2011/08/20(土) 00:50:24.230414デフォルトの名無しさん
2011/08/20(土) 08:46:38.540415デフォルトの名無しさん
2011/08/20(土) 08:54:19.63let 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前者の最適化は既に実装されてる
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それを証明出来るケースなんて、そう多くないぞ。
0418デフォルトの名無しさん
2011/08/20(土) 16:50:59.40linux x86-64版だと時間かかる処理でも一回実行すれば、メモリ簡約が効いて速くなるのに、winだと速くならん
同じ処理時間が掛かってる
0419デフォルトの名無しさん
2011/08/20(土) 17:25:34.61Linuxでメモリ簡約が効いていると判断した手段を用いて、Windowsでメモリ簡約が効いているかどうかを確かめてみる
0420デフォルトの名無しさん
2011/08/20(土) 17:27:45.63いや、だから使って見て明らかに効いてないんよ
0421デフォルトの名無しさん
2011/08/20(土) 18:46:44.53メモリ簡約ってのは初めて聞いた言葉だけど、メモ化のこと?
問題をもう少し絞り込みたいんだけど、
とりあえずコア言語レベルではどちらのOSでコンパイルしても同じなの?
それを再現できる可能な限り小さいプログラムのソースは提示できる?
0422デフォルトの名無しさん
2011/08/20(土) 18:51:43.25あと、+RTS -p オプションで出力した *.prof ファイルで、
問題の関数の entries や %time はどちらのOSでも同じなの?
他に *.prof ファイルで、Linux と Windows で違いは出てる?
0423デフォルトの名無しさん
2011/08/20(土) 18:52:33.82メモ化の事です
sum関数に時間が掛かってると感じる程度の、でかいリスト入れればおk
もう一度、同じ引数渡したら、普通はメモリ内を検索して結果を返すだけの時間しか掛からない
0424デフォルトの名無しさん
2011/08/20(土) 19:17:41.45申し訳ないが、具体的にあなたが試したコードを見せてくれないだろうか
原因が他に隠れている事は一切無いとは言い切れないし、
一字一句同一のコードで試したい
あと大事なことを忘れていた
各OSのバージョン、およびGHCのバージョンも教えてほしい
0425デフォルトの名無しさん
2011/08/20(土) 19:22:31.80問題の切り分けにすら不慣れなレベルで
8割くらい他の原因orただの勘違いと予想しておくよ
0426デフォルトの名無しさん
2011/08/20(土) 19:28:32.37最新のは知らんが、少し前までは自動ではメモ化しない方針だったはずだが
0427デフォルトの名無しさん
2011/08/20(土) 19:33:03.81ghci上だし、単純極まりないですよ?
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多分コンパイラも64bitかと
0429デフォルトの名無しさん
2011/08/20(土) 19:45:27.10GHC のバージョンを揃えて実験しろ
+RTS -p オプションで出力したプロファイラを比べろ
何度も言わせるな
これからこちらで ubuntu のデュアルブートの環境を作りますから、
それまでに完全なソースコードと、プロファイラの実験をお願いします
0430デフォルトの名無しさん
2011/08/20(土) 20:23:01.74■ このスレッドは過去ログ倉庫に格納されています