関数型プログラミング言語Haskell Part13
レス数が1000を超えています。これ以上書き込みはできません。
0001デフォルトの名無しさん
2010/10/10(日) 19:34:34ttp://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/
2chの仕様により、行頭の半角スペースは表示されません。
コードをインデントしたいときは、代わりに?または全角スペースを使うことができます。
0002デフォルトの名無しさん
2010/10/10(日) 19:37:23, ‐' ´ ``‐、 / ̄:三}
. /,. -─‐- 、. ヽ / ,.=j
_,.:_'______ヽ、 .! ./ _,ノ
`‐、{ へ '゙⌒ `!~ヽ. ! /{. /
`! し゚ ( ゚j `v‐冫 , '::::::::ヽ、/ そんなことよりDelphiしようぜ!
. {.l '⌒ ゙ 6',! / :::::::::::::::/ __
. 〈 < ´ ̄,フ .ノー'_ , ‐'´::::::::::::::;/ (_ノ)‐-、
. ヽ.、 ` ‐", ‐´‐:ラ ':::::::::::::::: ;∠. ヽ_} ゙ヽ
,.r` "´ /:::::::::::::::::::ィ´ `ゝ !、 /
/ / :::::::::::::::: ; '´ /´\ / r'\
. i ! ::::::::::::::/ 墨 | .!::::::::/ヽ、.._!ヽ. ヽ、
{ {:::::::::::;:イ / ‖i:::::::/:::::::::::::/ \
. ヽ ヽ,.ァ‐'´ /ヽ 二 ,/`ヽ、::::::::: /
0003デフォルトの名無しさん
2010/10/10(日) 19:37:56・関数型言語Part5
ttp://pc12.2ch.net/test/read.cgi/tech/1252470706/
・【数学者】Haskellはクソ言語【オナニー】
ttp://pc11.2ch.net/test/read.cgi/tech/1128011645/
・純粋関数型言語Concurent Clean
ttp://pc11.2ch.net/test/read.cgi/tech/1075629340/
・関数型言語ML (SML, OCaml, etc.), Part 6
ttp://pc11.2ch.net/test/read.cgi/tech/1245017721/
・Lisp Scheme Part30
ttp://pc12.2ch.net/test/read.cgi/tech/1270897776/
・【入門】Common Lisp その7【質問よろず】
ttp://pc12.2ch.net/test/read.cgi/tech/1270370267/
・Emacs Lisp 3
ttp://pc11.2ch.net/test/read.cgi/tech/1191875993/
・【Lisp】プログラミング言語 Clojure【JVM】
ttp://pc12.2ch.net/test/read.cgi/tech/1255533519/
・【.NET】F#について語れ【OCAML】
ttp://pc12.2ch.net/test/read.cgi/tech/1186030985/
0004デフォルトの名無しさん
2010/10/10(日) 19:38:17・Introduction to Functional Programming Using Haskell (2nd ed.)
ttp://www.amazon.co.jp/exec/obidos/ASIN/0134843460/
・Haskell: The Craft of Functional Programming
ttp://www.amazon.co.jp/exec/obidos/ASIN/0201342758/
・The Fun of Programming
ttp://www.amazon.co.jp/exec/obidos/ASIN/0333992857/
・The Haskell School of Expression: Learning Functional Programming Through Multimedia
ttp://www.amazon.co.jp/exec/obidos/ASIN/0521644089/
・入門Haskell
ttp://www.amazon.co.jp/exec/obidos/ASIN/4839919623/
・ふつうのHaskellプログラミング
ttp://item.rakuten.co.jp/book/4052963/
・Programming in Haskell
ttp://www.amazon.co.jp/exec/obidos/ASIN/0521692695/
・Real World Haskell
ttp://www.amazon.co.jp/exec/obidos/ASIN/0596514980
・関数プログラミングの楽しみ
ttp://www.amazon.co.jp/exec/obidos/ASIN/4274068056
0005デフォルトの名無しさん
2010/10/10(日) 19:43:18ttp://www.haskell.org/hoogle/
0006デフォルトの名無しさん
2010/10/10(日) 19:45:440007デフォルトの名無しさん
2010/10/10(日) 19:46:09ttp://learnyouahaskell.com/
Real World Haskell
ttp://book.realworldhaskell.org/read/
Tutorial From HaskellWiki
ttp://www.haskell.org/haskellwiki/Tutorials
0008デフォルトの名無しさん
2010/10/10(日) 20:06:04, ‐' ´ ``‐、 / ̄:三}
. /,. -─‐- 、. ヽ / ,.=j
_,.:_'______ヽ、 .! ./ _,ノ
`‐、{ へ '゙⌒ `!~ヽ. ! /{. /
`! し゚ ( ゚j `v‐冫 , '::::::::ヽ、/ そんなことよりC#しようぜ!
. {.l '⌒ ゙ 6',! / :::::::::::::::/ __
. 〈 < ´ ̄,フ .ノー'_ , ‐'´::::::::::::::;/ (_ノ)‐-、
. ヽ.、 ` ‐", ‐´‐:ラ ':::::::::::::::: ;∠. ヽ_} ゙ヽ
,.r` "´ /:::::::::::::::::::ィ´ `ゝ !、 /
/ / :::::::::::::::: ; '´ /´\ / r'\
. i ! ::::::::::::::/ 墨 | .!::::::::/ヽ、.._!ヽ. ヽ、
{ {:::::::::::;:イ / ‖i:::::::/:::::::::::::/ \
. ヽ ヽ,.ァ‐'´ /ヽ 二 ,/`ヽ、::::::::: /
0009デフォルトの名無しさん
2010/10/12(火) 17:54:160010デフォルトの名無しさん
2010/10/12(火) 20:16:24調子こくと自分でも何やってるのか分かんなくなるから
俺は、最近は関数を中置で使うことが多くなってる
こっちも、調子こくとエディタの編集画面かうざくなるが
a `fmap` b
0011デフォルトの名無しさん
2010/10/12(火) 20:27:19f <$> a <*> bを(| f a b |)と書くとか
ただしエラーメッセージが解読不能になる諸刃の刃
0012デフォルトの名無しさん
2010/10/13(水) 01:19:59そんなのあるんだ。
>>9じゃないけど、勉強になった。
サンクス。
0013デフォルトの名無しさん
2010/10/15(金) 09:00:270014デフォルトの名無しさん
2010/10/15(金) 09:08:210015Perl忍者 ◆M5ZWRnXOj6
2010/10/16(土) 16:44:43終了〜
0016デフォルトの名無しさん
2010/10/16(土) 21:59:420017デフォルトの名無しさん
2010/10/17(日) 12:52:460018デフォルトの名無しさん
2010/10/18(月) 12:46:53俺もちょっと前から少しずつ読んでる
15ページ目でいきなり躓いてるがな
0019デフォルトの名無しさん
2010/10/18(月) 12:52:49Plugging a Space Leak with an Arrow
Arrow 以前の実装で起きてたスペースリークを
Arrow で解決した話が詳細に書かれている
0020まつもとひろゆき
2010/10/18(月) 17:07:350021デフォルトの名無しさん
2010/10/18(月) 17:54:48IP抜きました
本人確認
0022デフォルトの名無しさん
2010/10/18(月) 18:10:330023デフォルトの名無しさん
2010/10/18(月) 20:16:560024デフォルトの名無しさん
2010/10/18(月) 21:13:330025Perl忍者 ◆M5ZWRnXOj6
2010/10/18(月) 23:56:0120〜24だけをみると
まるでHaskell板の面影すらありません
そう思いますよね???
0026デフォルトの名無しさん
2010/10/19(火) 00:10:480027Perl忍者 ◆M5ZWRnXOj6
2010/10/19(火) 09:33:280028Perl忍者 ◆M5ZWRnXOj6
2010/10/19(火) 09:38:45くそみてええなのは含まれません!
0029デフォルトの名無しさん
2010/10/19(火) 10:06:10モダンってどんな書き方?
0030デフォルトの名無しさん
2010/10/19(火) 10:11:390031デフォルトの名無しさん
2010/10/19(火) 10:12:30有益な情報を一切ださない奴。
0032デフォルトの名無しさん
2010/10/20(水) 10:44:140033Perl忍者 ◆M5ZWRnXOj6
2010/10/20(水) 11:31:10haskellじゃねーぞ
プログラマと1回 FPSをやってみたいんだけど
お前らができるFPSをいってくれ 俺はそれをダウンロードしてスタンバイするので
0034デフォルトの名無しさん
2010/10/20(水) 12:01:130035Perl忍者 ◆M5ZWRnXOj6
2010/10/20(水) 12:11:30早くFPSのゲーム名いえよ
0036デフォルトの名無しさん
2010/10/20(水) 12:18:450037Perl忍者 ◆M5ZWRnXOj6
2010/10/20(水) 12:24:26はやくURLはれ
0038デフォルトの名無しさん
2010/10/20(水) 12:30:490039デフォルトの名無しさん
2010/10/20(水) 18:59:530040デフォルトの名無しさん
2010/10/20(水) 20:34:010041デフォルトの名無しさん
2010/10/20(水) 20:50:230042デフォルトの名無しさん
2010/10/20(水) 21:37:090043デフォルトの名無しさん
2010/10/20(水) 22:52:52http://blog.livedoor.jp/perlninja/ これ何?
0044Perl忍者 ◆M5ZWRnXOj6
2010/10/20(水) 23:00:21俺の偽だろ!!!
ガッチムッチの思い切り!ガッチムチ羽ばたいて!飛んで飛んでアソコへ!レディゴーレディゴー!レディゴー!(ガチガチ! oh〜ガチムチー!!!
0045デフォルトの名無しさん
2010/10/20(水) 23:15:35使えるのなら、小粒でいいから何かテクニックでも紹介していけ
使えないのなら、邪魔だから騒がしくするな
0046デフォルトの名無しさん
2010/10/21(木) 00:00:45小難しいモナドでつまづいてます。
皆さん何を勉強してモナドが何者か納得できましたか?
とりあえずWadlerの論文みつけたので、
これ読めばなんかつかめるかなとは期待してるんですが、英文だし効率悪い。
0047デフォルトの名無しさん
2010/10/21(木) 00:12:11Haskellを使うためにモナドを勉強するならこれで十分だと思います。
世界で一番か二番くらいにやさしい「モナド入門」
http://d.hatena.ne.jp/m-hiyama/20060419/1145432492
0048デフォルトの名無しさん
2010/10/21(木) 00:27:28おすすめのページじっくり読んでみます。
まずはお礼まで。
0049デフォルトの名無しさん
2010/10/21(木) 07:56:25[モナド] を理解することと、
[モナドで副作用を閉じ込める仕組み(IO モナド)] を理解することは別だからね。
[モナド] と [モナドの演算] というのは、有理数と割り算みたいなもの。
[有理数]
1. 整数 x を □/1 でくるめば(x/1)有理数になる(整数を有理数に変換)
2. 有理数どうしならば割り算(÷)という特別な演算ができる
3. 割り算した結果できたものもまた有理数だ
4. 有理数には特別な性質がある(4/8 も 2/4 も既約分数にすれば同じとか、ゼロでは割れないとか)
[モナド]
1. 何でもいいが何か x を return □ でくるめば(return x)モナドになる(何かをモナドに変換)
2. モナドどうしならバインド(>>= や >>)という特別な演算ができる
3. バインドした結果できたものもまたモナドだ
4. モナドには特別な性質がある(モナド則とよばれるルール)
モナドとは本質的に何か探るのではなく、こういうことができるものにモナドと名前が付いてる、
という方向からモナドを理解するやりかたもあるよ。
どちらも 1. と 3. は何も特別なことはなく、各々の特徴は 2. と 4. に現れている。
だから 2. と 4. がどのようなものかを知れば、モナドが見えてくるよ。
0050Perl忍者 ◆M5ZWRnXOj6
2010/10/21(木) 08:08:020051Perl忍者 ◆M5ZWRnXOj6
2010/10/21(木) 08:11:150052デフォルトの名無しさん
2010/10/21(木) 09:07:49問題は、隠蔽するやり方が何通りもあったために、かえって偶有的属性が増えてしまった
ということだと思います。
005349
2010/10/21(木) 09:09:35すまん、[モナド] の 2. は違うな
バインドはモナドどうしの演算じゃなかった
[モナド] と [そのモナドで包んでるものに対する関数] との演算だったよ
あと、[有理数] の 1. は別に整数でなくてもいい
複素数でもその他でもいいが、整数が一番簡単だったから
0054デフォルトの名無しさん
2010/10/21(木) 12:54:25>モナドの目的は、本来の目的を情報隠蔽することだと思います。
どういうこと?
たとえば、ある代数データ型をある目的で使いたいが、その目的を隠したい、
そういう時にその代数データ型をモナドにすることを考えてみるといい、
ということですか?
0055デフォルトの名無しさん
2010/10/21(木) 13:01:170056デフォルトの名無しさん
2010/10/21(木) 15:20:32しかし、つまらないという基準はただの主観だと思います。
0057デフォルトの名無しさん
2010/10/21(木) 15:34:43あなたはこの世界を五感と知性によって認識しているでしょう。
0058Perl忍者 ◆M5ZWRnXOj6
2010/10/21(木) 23:44:59おもしろいの基準あがってるからしょうがねえんだよかす
0059デフォルトの名無しさん
2010/10/21(木) 23:47:18オブジェクト(≒集合の元)を「モナド」と呼んでる段階で眉に唾をつけたくなる.
0060Perl忍者 ◆M5ZWRnXOj6
2010/10/21(木) 23:49:01てめえ
うちはイタチの真似してんだろこら
「人は己の知識や認識に頼り縛られ生きている…それを現実と呼んでな。しかし現実とはあいまいなものだ。それは幻かもしれない
お前もNARUTO好きか?
0061デフォルトの名無しさん
2010/10/22(金) 03:20:06仏教思想で答えただけなんだがな・・・
仏教では、世界とは八識(五感+意識+末那識+阿羅耶識)で物事を認識することによる主観の産物だっていうのが定説。
006249
2010/10/22(金) 07:32:55俺自身も書いた後でこの捉え方はどうかとちょっと疑問だった。
(いろいろ突っ込みどころはあるだろうし)
が、少なくともオブジェクト(≒集合の元)を「モナド」と呼んだつもりはないのだが。
[モナド] の 3. のところがマズったか。
小学校や中学校、高校で「割り算とは何ものか?」という本質は学ばず、
「割り算は**という演算だよ」とだけ教えられ、さっさと学習を進めたはず。
微分、積分、内積なども同じだと思う。
ちょっと前に Haskell 勉強しはじめた者も Haskell に関しては同じ立場だから、
「モナドは**という演算ができて、##という性質があるよ」
の**と##をまず調べたらどうかと言いたかった。
それはモナドの理解のほんの一部だけだけど、
それだけでも Haskell の学習を進めるのには十分だから。
0063Perl忍者 ◆M5ZWRnXOj6
2010/10/22(金) 07:38:550064デフォルトの名無しさん
2010/10/22(金) 08:09:18「1を return でくるめば(return 1)モナドになる」
「(Just x) と (Left y) (モナド同士)に特別な演算ができる」
って変でしょ?
(return 1)の属する型(IO Int なり Maybe Int なり)と演算 >>=, >>, return の組がモナド.
あなたの書き方だといつでもモナドの元同士に対する演算が定義されていると読めて,
データを型で区別してプログラムの質を高める,という考え方と真っ向から対立し
読者に混乱を引き起こす.
0065デフォルトの名無しさん
2010/10/22(金) 11:05:26これならここの住人にも理解できるんじゃないか。
0066デフォルトの名無しさん
2010/10/22(金) 11:57:35一度その型で始めたら途中変更は利きませんからね
って事ですかね
0067デフォルトの名無しさん
2010/10/22(金) 12:37:22と問われたら違うというほかない
006849
2010/10/22(金) 12:39:49演算はモナドどうしではなかったと >>53 で訂正したぞ
(>>=、>> の右辺はモナドじゃないから)
>>66
できるよ
[String] から [Int] に変更できるでしょ
0069デフォルトの名無しさん
2010/10/22(金) 12:40:300070デフォルトの名無しさん
2010/10/22(金) 12:43:54変な理屈だけ増やしてどうすんだろな
モナドを使わずに書いた場合と比べてみれば
少しはありがたみが分かる
0071デフォルトの名無しさん
2010/10/22(金) 12:51:54>初心者が具体例なしに理屈だけ聞いて分からないから困ってんのに
そんなこと一言も聞いてないが
逆に例ばかりで理屈が分からないとも聞いてないけどね
自分が知りたいんだと素直に言ったら?
0072デフォルトの名無しさん
2010/10/22(金) 13:02:520073デフォルトの名無しさん
2010/10/22(金) 13:38:550074デフォルトの名無しさん
2010/10/22(金) 13:48:10お釈迦さんバカにすんあ
0075デフォルトの名無しさん
2010/10/22(金) 14:46:430076デフォルトの名無しさん
2010/10/22(金) 17:21:280077デフォルトの名無しさん
2010/10/22(金) 19:53:05他人の主観に便乗するやつはゴミ
0078デフォルトの名無しさん
2010/10/22(金) 20:10:37という主観ですね
0079デフォルトの名無しさん
2010/10/22(金) 20:27:570080デフォルトの名無しさん
2010/10/22(金) 20:32:170081デフォルトの名無しさん
2010/10/22(金) 20:40:200082デフォルトの名無しさん
2010/10/22(金) 20:53:23そんな側面はありません
0083デフォルトの名無しさん
2010/10/22(金) 21:28:41今ほっとな話題は仏教だよ
0084Perl忍者 ◆M5ZWRnXOj6
2010/10/22(金) 23:22:49一瞬ここのスレみたら
仏教スレになってた
テラワロスwwwww
0085デフォルトの名無しさん
2010/10/23(土) 01:13:280086デフォルトの名無しさん
2010/10/23(土) 09:13:370087デフォルトの名無しさん
2010/10/24(日) 18:18:17Perl忍者!頼んだぞ!
0088デフォルトの名無しさん
2010/10/24(日) 18:56:06紀元前500年のインドはオカルト宗教であるバラモン教が力を持っていたが、
そのアンチテーゼとして釈迦の教えをまとめたのが仏教(上座部仏教)だ。
神に祈れば天国に行ける?バカをいうなw
仏陀は弟子にこういった、
小石を池に投げ込んで、浮かんでこい、浮かんでこい、と念じれば小石は浮かんでくるのか?
いや、浮かんできはしない。
念仏や祈祷や呪文を唱えたところで何も変わらんのだ。
そのくだらん映画を今すぐ取りやめろ。
0089デフォルトの名無しさん
2010/10/24(日) 19:02:31この大乗仏教というやつは仏陀の教えを経典主義的に極端な形で屁理屈をこね回して作られたオカルト要素たっぷりのゴミ宗教だ。
そう、どんな素晴らしい教えでも凡人にかき回されるとゴミに変貌するわけだ。
Haskellだって、凡人が大量に使うようになると当初の理想なんて失って優柔不断な言語になるに決まっている。
だからperl忍者とかいうザコはどうしてもHaskell触りたいなら博士号取ってからにしろ。
0090デフォルトの名無しさん
2010/10/24(日) 19:27:54世間が求めているのは便利なものだ。
大乗仏教は人々に支持された。
Haskellは?
0091デフォルトの名無しさん
2010/10/24(日) 19:29:250092デフォルトの名無しさん
2010/10/24(日) 19:52:170093デフォルトの名無しさん
2010/10/24(日) 20:33:13少なくとも嫌ってる人は少ないだろうな
大半は「好き」「はぁ?何それ」 のどちらかだろ
0094デフォルトの名無しさん
2010/10/24(日) 21:37:370095デフォルトの名無しさん
2010/10/25(月) 06:40:220096デフォルトの名無しさん
2010/10/25(月) 12:13:280097(信は力なり)Perl忍者 ◆M5ZWRnXOj6
2010/10/25(月) 23:27:04最後の行にPerl忍者とかかかれてもきずかないんですが
死ねよハゲ
0098デフォルトの名無しさん
2010/10/25(月) 23:59:22John Hughes が著わした次の論文を紹介する。
Generalising Monads to Arrow
モナドの利点も簡潔にまとめてあるから、
モナドって何の役に立つんだ? という人にも参考になる。
0099デフォルトの名無しさん
2010/10/26(火) 00:01:42論文のタイトルが間違ってた。
細かいことだが著者に失礼なので訂正させてほしい。
Generalising Monads to Arrows
0100デフォルトの名無しさん
2010/10/26(火) 13:39:101. Stateモナドを一回写経
2. loop :: Monad m => Int -> m a -> m a とか、when :: Monad m => Bool -> m a -> m aのような
『モナドをとってモナドを返す』関数をいろいろ作り、Stateモナド内では何が起きているのかを考える
3. 全部消してStateモナドを記憶を頼りに再実装
ってやればかなり理解できる。
Listモナドは、リスト内包表現をListモナドで表現するのを繰り返していれば、分かってくる。
Maybeモナドはその劣化版。
これらはすべて一本道の逐次計算あるいは逐次実行、すなわちモナドが抽象化しているものの具体例になるんだけど、
そこまで行く前に、StateモナドとListモナドを別々に理解して、いつでもモナドのインスタンスとして再実装できるようになるほうが、
数学者でなければ結局は早いと思う。
いずれ、Listモナドは量子ピタゴラススイッチなのだと理解できる日が来よう。
0101デフォルトの名無しさん
2010/10/26(火) 18:15:32>Maybeモナドはその劣化版
何となくだけど、ちょっとだけ引っかかる。
Monad クラスのインスタンスは全て等しく優劣無くモナドなんじゃないの?
何の視点で優劣を比べた結果 Maybeモナド が List モナドに劣ると考えたの?
0102デフォルトの名無しさん
2010/10/26(火) 19:37:57もちろん、処理系が提供しているものに関しては整合性がとれるように設計されているはずだが。
0103デフォルトの名無しさん
2010/10/26(火) 20:11:35僕の誤解でなければ、[a]の値をaを0個か1個持つものだけに制限すると、
理論的(代数的)にはMaybe aとまったく同じもので、
それはMonadoクラスとしての働きもまったく同じはず。
0104デフォルトの名無しさん
2010/10/26(火) 20:14:47サーセン。
0105デフォルトの名無しさん
2010/10/26(火) 20:18:58Data.Maybe.maybeToListを使うと、Maybeの値をリストに変換でき、さらにこの変換がMonadインスタンスと整合する
整合するというのは以下の二つの法則が成り立つこと(なんか圏論の臭いがする)
maybeToList (return x) = return x
maybeToList (x >>= f) = maybeToList x >>= maybeToList . f
0106デフォルトの名無しさん
2010/10/26(火) 21:17:22なるほど、数学的には リストモナドは Maybe モナドを含んでいること、
その観点で Maybe モナドはリストモナドの劣化版だと言ったのは理解した
同意する
ただ、ちょっと確認しておきたい
数学的には同じでも、実際問題としてプログラムソースの中で Maybe a を使ってた所を全て
劣化版を完全版にしようとして要素が0個か1個の [a] で置き換えたらまずいよな?
ソースを保守しにくくなるよな?
そういう観点では、リストと Maybe は優劣を比べるものではなく、
むしろ全く別の役割のものだよな?
0107デフォルトの名無しさん
2010/10/26(火) 21:19:22すまん、>>106 の後半は >>105 に対してだ
0108デフォルトの名無しさん
2010/10/26(火) 21:33:09横レスだけど、MaybeをListに置き換えると、
要素は0個か1個、という制約が抜け落ちてしまうから
置き換えることは出来るにしても、設計的には酷くなるからやめた方がいい
誤解に対しては、「劣化版」じゃなくて「特殊化版」って語を使えば良かっただけの話じゃないかな
0109デフォルトの名無しさん
2010/10/26(火) 21:52:11newtypeなんか劣化の極みになるんじゃねいの
0110デフォルトの名無しさん
2010/10/26(火) 22:05:48「モナドとして、returnと(>>=)で操作する限りにおいては」リストを不自由にしたものに過ぎないと言えるけど、
値を取り出すことやその他の操作を考えれば劣化じゃないし、もちろんコーディング上の役割は違う
0111100, 103
2010/10/27(水) 00:38:57>>100 で言いたかったことは…
リストモナドの働きを理解すればその特殊化版であるMaybeモナドの働きも理解できるよ、
それと、IOモナドはStateモナドで理解できるから(Rreaderモナドなども)、
ひとまずStateモナドとMaybeモナドを理解すれば十分に視野が開けるよ、
ということです。
もちろん、何かを理解するための試行錯誤の上ではなく、
実用のコード上で、一般にMaybe aをList aに置き換えてしまうのは危険です。
0112デフォルトの名無しさん
2010/10/29(金) 12:38:17・Maybeモナドは、Listモナドの要素数を0か1に制限した
特殊な例であるという見方ができる
・Monadクラスのインスタンスがモナドであるとは限らない
・Perl忍者は電波である
0113デフォルトの名無しさん
2010/10/30(土) 11:37:27・「コンパイルできたら安全」とは限らない
ここからの議論を期待します
0114デフォルトの名無しさん
2010/10/30(土) 12:27:410115デフォルトの名無しさん
2010/10/30(土) 12:32:25カプセル化と多態はそのための機能がある。実装の継承の仕組みはない
メッセージ渡しはちょっと無理があるかも
0116デフォルトの名無しさん
2010/10/30(土) 13:05:53data Visitor a b c = Visitor (a -> c) (b -> c)
accept (Acceptor accept) visitor = accept visitor
leftAcceptor x = Acceptor accept
where accept (Visitor visitLeft visitRight) = visitLeft x
rightAcceptor x = Acceptor accept
where accept (Visitor visitLeft visitRight) = visitRight x
0117デフォルトの名無しさん
2010/10/30(土) 13:13:260118デフォルトの名無しさん
2010/10/30(土) 13:53:460119デフォルトの名無しさん
2010/10/30(土) 14:45:04与えられた長さの順序リスト生成器を生成するようなことが書かれていますが、
vector 関数のような引数は無いですよね。
どうやって長さを指定するのでしょうか。
resize 関数を作用させるしかないですか?
0120デフォルトの名無しさん
2010/10/31(日) 18:46:370121デフォルトの名無しさん
2010/10/31(日) 19:03:15orderedListの定義はsort `fmap` arbitraryだからのぅ
fmap sort . vectorで代用すりゃいいんとちゃうか?
0122デフォルトの名無しさん
2010/10/31(日) 19:38:080123デフォルトの名無しさん
2010/10/31(日) 21:03:22なんか解説と違ってていまいち納得いかないが、
実用上はそれで問題ないような気がしてきた
ありがと
0124デフォルトの名無しさん
2010/10/31(日) 23:13:45同じ名前で異なるメソッドが呼ばれると嫌がられる気がする
高階関数は良いが、関数のタプルとか関数のリストとかはだめっぽい
0125デフォルトの名無しさん
2010/10/31(日) 23:27:130126デフォルトの名無しさん
2010/10/31(日) 23:39:36ちょっとまった。 Haskell でもオーバーロードがあるだろ。
0127デフォルトの名無しさん
2010/11/01(月) 00:46:36あるね
オーバーロードも嫌がられる場合がある
例えば、MaybeなのかListなのかはっきりしろ、みたいな
0128デフォルトの名無しさん
2010/11/01(月) 18:42:330129デフォルトの名無しさん
2010/11/01(月) 19:58:16その型変数もシグネチャに取り入れた関数を定義したいです。
次のようなイメージの型クラスです。
class P (p a) where
ext :: p a -> a
で、次のようなデータ型を用意し
data Test a = T (a, a)
次のようにインスタンスを宣言したい。
instance (Num a) => P (Test a) where
ext (T (x, y)) = x + y
しかしこれでは型クラスの定義の class P (p a) where の所でエラーが出ます。
Type found where type variable expected
本来 class P のすぐ後には型変数が来るべきですが (p a) と書かれていて、
型変数が書かれていないといった旨のエラーだと思います。
このようーな型クラスは作れるのでしょうか。
作れるのなら、どのような方法で作れるでしょうか。
0130デフォルトの名無しさん
2010/11/01(月) 20:05:05これでは駄目?
class Monad m where
return :: a -> m a
0131130
2010/11/01(月) 20:10:07GHC拡張を使っていいなら
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
class P p a where
ext :: p a -> a
data Test a = T (a, a)
instance (Num a) => P Test a where
ext (T (x, y)) = x + y
0132デフォルトの名無しさん
2010/11/01(月) 20:33:16> GHC拡張を使っていいなら
全く問題ないです。
ありがとうございます。
助かりました。
0133デフォルトの名無しさん
2010/11/02(火) 10:22:19型システムの表現力を見積もる基準とかってある?
0134Perl忍者 ◆M5ZWRnXOj6
2010/11/04(木) 17:10:49どうせゴミだろ
0135100, 103
2010/11/04(木) 18:14:26とりあえず、Agdaのような「値」を型構築子の引数にとれるものと、
それができないHaskellのようなものの間には、原理的な違いがあると思う。
0136デフォルトの名無しさん
2010/11/04(木) 18:15:11論文
0137デフォルトの名無しさん
2010/11/04(木) 18:25:420138デフォルトの名無しさん
2010/11/04(木) 20:15:440139デフォルトの名無しさん
2010/11/06(土) 22:50:1710章の246ページで挫折しました。
コードが何やってるか分かりません。
0140デフォルトの名無しさん
2010/11/06(土) 22:55:09なんだ、クイックソートか・・・
よく読めとしか言いようがない。
0141デフォルトの名無しさん
2010/11/06(土) 22:58:32どんなコード?最初の数行だけでもいいから貼ってくれ
あと節の名前(ボイラープレートをなんちゃらとか、グレイスケールファイルとかそういうタイトル)
0142デフォルトの名無しさん
2010/11/06(土) 23:11:14newtype Parse a= { runParse :: ParseState -> Either String (a, ParseState) }
identify :: a -> Parse a
identify a Parse (\s -> Right (a, s))
0143デフォルトの名無しさん
2010/11/06(土) 23:34:25newtype宣言の説明は省略するけど
newtype Parse aのaはそのパーサが成功したときaという型のデータを返すという事
ParseStateはパースしたいデータ、入力だ
でパースはいつも成功するとは限らない、そして失敗したときにそのエラーの情報を持っておきたい
なのでEitherがくるわけだ、そしてこの場合そのエラー情報はStringに決めうちしておくわけだな
でパースが成功したときは読み取るのに成功したデータと、入力データのうちそのパース時に使われなかった分を返すと
でそれがEitherの第二引数の型(a,ParseState)になるわけだ
で次にidentity
一言で言っちゃうとどんな時でもある値を返すパーサの定義だな
試しにrunParse (identity 1) undefinedを展開すると
identityの定義より runParse (Parse (\s -> Right (1,s)) undefined
runParseアクセッサの定義より (\s -> Right (1,s) undefined
関数適用より Right (1,undefined)
さてこの説明で分からなかったことに対する質問をどうぞ
0144デフォルトの名無しさん
2010/11/07(日) 00:01:090145Perl忍者 ◆M5ZWRnXOj6
2010/11/07(日) 11:43:470146デフォルトの名無しさん
2010/11/07(日) 11:57:590147デフォルトの名無しさん
2010/11/07(日) 18:15:38ワロタ、消えたかと思ったのに
0148Perl忍者 ◆M5ZWRnXOj6
2010/11/07(日) 18:50:16NARUTOみろ
暁vsカカシ
0149Perl忍者 ◆M5ZWRnXOj6
2010/11/07(日) 18:53:490150デフォルトの名無しさん
2010/11/07(日) 19:18:43http://www.youtube.com/watch?v=itnQMJFRzAI
これきいてます
0151デフォルトの名無しさん
2010/11/08(月) 18:45:44だれか解説お願いします。
0152デフォルトの名無しさん
2010/11/08(月) 23:10:42StdGenのインタフェースはRandomGenクラスのメソッドで、もしInt乱数に特化したければその定義は変えられるし、本物の乱数装置が手元にあるのなら、それを発生源として本物の乱数を発生させる実装も可能だよ。
ということでは。
0153デフォルトの名無しさん
2010/11/09(火) 19:57:26括弧はぶいて見やすくしてるだけという認識でおけ?
0154デフォルトの名無しさん
2010/11/09(火) 20:19:57細かいことを言うと、
・後ろだけじゃなくて前にも括弧をつける: (f . g $ x)は((f . g) x)の意
・($)は特別な構文じゃなくてPreludeで定義された演算子(右結合、強度1)
0155デフォルトの名無しさん
2010/11/09(火) 20:21:350156デフォルトの名無しさん
2010/11/09(火) 20:30:15randomR (数値, 数値) の結果が RandomGen->(数値, RandomGen) で、
StdGenがRandomGen のインスタンスだから問題ない、と
StdGen以外でもRandomGenのインスタンスを用意すればいい、と
twoBadRandomsの中に random が説明もなく出てきたんですけど、これは何でしょうか?
0157デフォルトの名無しさん
2010/11/09(火) 21:00:29サンクス
0158デフォルトの名無しさん
2010/11/09(火) 21:21:44関数や型、型クラスなどが説明もなく出てきた時は、
まずは標準ライブラリのドキュメントを調べてみてください。
ドキュメントの Index を使えば楽に調べられます。
random 関数は Random 型クラスが定義している関数のひとつです。
randomR 関数もおなじ型クラスが定義している関数のひとつですが、
それとは違い random 関数は乱数の範囲を明示せず、
デフォルトの範囲が使われます。
0159デフォルトの名無しさん
2010/11/09(火) 21:51:05やっぱり、GHCとドキュメントをインストールして使いながら読まないとダメか…
0160デフォルトの名無しさん
2010/11/09(火) 22:02:54使わないで 360 ページまで理解できたのなら凄いですね
0161デフォルトの名無しさん
2010/11/10(水) 05:17:490162Perl忍者 ◆V8M/4amdko
2010/11/10(水) 17:13:35なーむーん
0163デフォルトの名無しさん
2010/11/10(水) 18:07:490164デフォルトの名無しさん
2010/11/10(水) 22:27:280165Perl忍者 ◆M5ZWRnXOj6
2010/11/10(水) 22:35:180166デフォルトの名無しさん
2010/11/10(水) 22:44:09これこそが贅沢
これこそがステータス
役に立つことしかやる余裕がない人はPerlでメモ帳でも作ってろ
0167デフォルトの名無しさん
2010/11/11(木) 11:57:450168デフォルトの名無しさん
2010/11/11(木) 12:16:02何しろ人事担当も経営者も関数型言語の将来性なんて一つも理解していないのだからw
0169デフォルトの名無しさん
2010/11/11(木) 13:29:170170デフォルトの名無しさん
2010/11/11(木) 13:56:56むしろ底辺の一部のベンチャーほど理解してると思うなぁ。
0171デフォルトの名無しさん
2010/11/11(木) 14:23:370172デフォルトの名無しさん
2010/11/11(木) 14:43:16言語が使えるとか使えないという初級レベルの話はしていないと思うなぁw
0173デフォルトの名無しさん
2010/11/11(木) 15:34:54この金やるからどっかに消えろ
by ソクラテス
0174デフォルトの名無しさん
2010/11/11(木) 15:36:06さすが馬鹿は発想が貧弱だな
0175Perl忍者 ◆M5ZWRnXOj6
2010/11/11(木) 16:54:19方程式とかなw
難しくみせて 実は簡単なことやってる低レベルなやつらねw
バカだから知的にみらたいでしょ?w
そろそろ死んだ方がいいよw
0176デフォルトの名無しさん
2010/11/11(木) 17:17:340177デフォルトの名無しさん
2010/11/11(木) 18:16:35あと、忍者熱烈支持!!!
0178デフォルトの名無しさん
2010/11/11(木) 18:18:11お前自分のレスを読み返してみてどんなことを思う?
0179デフォルトの名無しさん
2010/11/11(木) 18:24:130180デフォルトの名無しさん
2010/11/11(木) 18:42:50銀行員とか書けば良いんだろうか?或は、議員だとか。
何かこう…
0181デフォルトの名無しさん
2010/11/11(木) 18:45:010182デフォルトの名無しさん
2010/11/11(木) 19:16:130183デフォルトの名無しさん
2010/11/11(木) 19:21:510184デフォルトの名無しさん
2010/11/11(木) 19:32:290185デフォルトの名無しさん
2010/11/11(木) 19:37:44ninja-って言ってる
0186デフォルトの名無しさん
2010/11/11(木) 19:40:460187Perl忍者 ◆M5ZWRnXOj6
2010/11/11(木) 19:54:120188Perl忍者 ◆M5ZWRnXOj6
2010/11/11(木) 20:01:18お前がふけ
>>177
忍者熱烈支持!!! って韓国人みたい
>>178
ほんとに低レベルだと思う
>>179
知り合いが店つくったときのIT化
事務術
>>180
しねw
>>181
死ねw
>>182
大名殺しとかPerl業界の破壊工作
S級犯罪者 ビンゴブックにも載ってるけどな
>>185
外人がわめいてる
0189Perl忍者 ◆M5ZWRnXOj6
2010/11/11(木) 20:08:03影武者がいる
全て共有してるからな 俺を潰したければ本物を見つけてみろ
0190デフォルトの名無しさん
2010/11/11(木) 20:21:310191デフォルトの名無しさん
2010/11/11(木) 20:47:19じゃあ九割五分までが底辺だな。w
0192デフォルトの名無しさん
2010/11/11(木) 21:02:080193デフォルトの名無しさん
2010/11/11(木) 21:03:010194デフォルトの名無しさん
2010/11/11(木) 21:03:13話題によるスレの使い分けにご協力願います。
Perl忍者です Perlプログラマになりたいです
http://hibari.2ch.net/test/read.cgi/tech/1284704280/
0195デフォルトの名無しさん
2010/11/11(木) 21:05:44知恵遅れのPerl忍者。w
0196デフォルトの名無しさん
2010/11/11(木) 21:47:440197デフォルトの名無しさん
2010/11/11(木) 22:06:30驚愕の事実だな
0198デフォルトの名無しさん
2010/11/12(金) 05:03:080199Perl忍者 ◆M5ZWRnXOj6
2010/11/12(金) 17:14:08「動画プレイヤーの開発です」
好きな言語はなんですか
「PHPとASです」
なにできる?
「Flash使って動画プレイヤー」
俺「プッ(笑)
「Twitterアプリもつくりましたよ」
みせてください
俺「へー(苦笑
0200デフォルトの名無しさん
2010/11/12(金) 18:00:450201デフォルトの名無しさん
2010/11/12(金) 18:01:40>>197
0202デフォルトの名無しさん
2010/11/12(金) 20:20:57GHC の拡張なんかでできますか?
たとえば次のような感じです。
let f a b c = a * (b + c)
in 2 `f 10` 3
予め g = f 10 としておけば 2 `g` 3 でできますが、
上記のように記述できるかなと。
べつに目的はないです。
これが分かりやすいかどうかも考えてません。
単に Haskell で遊んでて、ふと思ったもので。
0203デフォルトの名無しさん
2010/11/13(土) 01:38:190204デフォルトの名無しさん
2010/11/13(土) 13:31:57素っ気ないな
でも、ありがと
0205デフォルトの名無しさん
2010/11/13(土) 15:15:560206デフォルトの名無しさん
2010/11/13(土) 19:48:270207デフォルトの名無しさん
2010/11/13(土) 21:37:530208デフォルトの名無しさん
2010/11/14(日) 00:07:27それとも解答例なんか見るまでもなく簡単にできるものなんでしょうか?
0209デフォルトの名無しさん
2010/11/14(日) 00:17:07なんかでググればいろいろ出てくるでしょ
ネットで読める原書 http://book.realworldhaskell.org/read/
にある各 Exercises のコメ欄にも、回答例のコメントが付いてるのが所々ある
0210デフォルトの名無しさん
2010/11/14(日) 12:18:13-- ここから
import GHC.IOBase
import System.Cmd
wgetCmd :: String
wgetCmd = "./wget/wget" -- wget.exe というコマンドがwgetというフォルダの下にある
wgetParam :: String -> [String]
wgetParam url = ["-r", "-l1", "--no-parent", "-A.jpg", "--header=REFERER:"++url, "-U", "\"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)\"", url, "-e", "robots=off"]
testMain = do
iStr <- readFile "dList2.txt" -- 行頭にタブ dList2.txt に画像のURLが1行にひとつずつある
let ls = lines iStr -- 行頭にタブ
wgetMain ls -- 行頭にタブ
wgetMain :: [String] -> IO GHC.IOBase.ExitCode
wgetMain [] = return GHC.IOBase.ExitSuccess
wgetMain (u:us) = do
rawSystem wgetCmd $ wgetParam u -- 行頭にタブ
wgetMain us -- 行頭にタブ
-- ここまで
WindowsXPで、ghciの中
で :m System.Cmdの後にtestMainでとりあえずちゃんと動きました
他に、wgetみたいな関数があったら教えてください
0211デフォルトの名無しさん
2010/11/14(日) 14:19:06ぱっと見たところ、wgetMain 関数の中は forM_ 関数を使えば
空リストとの場合分けを書かなくて済む。
> 他に、wgetみたいな関数があったら教えてください
haskell の packageDB に http-wget というライブラリがある。
http://hackage.haskell.org/package/http-wget
きみと似たようなことをしてる(wget コマンドのラッパー)。
このライブラリを使えば、とりあえず
(_, b) <- wget' "http://・・・hoge.gif" [] []
という記述で b に GIF ファイルの本体が String 型で書き込まれた。
後は標準ライブラリの withBinaryFile 関数を使って、
withBinaryFile "c:\\・・・hoge.gif" WriteMode (\h -> hPutStr h b)
と記述すれば保存されたよ。
ただ、wgwt コマンドにどのようなパラメータを渡しているのかは知らない。
公開されている関数の中には、詳細なパラメータを渡す類のものは無さそうだけど、
デフォルトがどうなってるのかは自分で調べてくれ。
ソースを見れば何やってるのか分かるだろうし。
0212デフォルトの名無しさん
2010/11/14(日) 14:24:26あ、ごめん。
wgetMain 関数は空リストだったり成功したら ExitSuccess を「ひとつ」返すのか。
それなら forM_ や forM では意味無いね。
成功や失敗のリストを返すのなら forM を使えばいいけど。
ごめん、>>211 の前半は無視してくれ。
0213デフォルトの名無しさん
2010/11/14(日) 16:29:040214デフォルトの名無しさん
2010/11/14(日) 16:48:45(h, b) <- wget' "http://・・・hoge.gif" [] []
とやって、ヘッダの内容を確認してもダメだった?
それでもダメなら、b の先頭数文字くらいのマジックコードで、
画像ファイルかどうかを判別するとか
0215デフォルトの名無しさん
2010/11/14(日) 16:54:42もし404じゃないのが来るようなら自前で判断するコード書く必要がある
0216215
2010/11/14(日) 16:55:500217デフォルトの名無しさん
2010/11/14(日) 17:57:58HTMLテキストファイルから画像のURLを抽出するスクリプト作ってみた
これと>>210で画像だけダウソできる(ふたばの二次裏junで確認したけど、多用するとアク禁されると思う)
↓ここから(GetURL.hs)
-- ghci → :load GetURL.hs → getImageURL "HTMLのソースコードが書いてあるテキストファイル" "結果を出力するファイル"
import Text.Regex.Posix
import System.FilePath
import Data.Char (toLower)
urlPat = "s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+"
getImageURL :: FilePath -> FilePath -> IO ()
getImageURL inFile outFile = do
{-タブ-} inStr <- readFile inFile
{-タブ-} writeFile outFile $ unlines $ (filter isNotThumb) $ (filter isImageURL) $ ((inStr =~ urlPat) :: [String])
isImageURL :: String -> Bool
isImageURL url =
{-タブ-} case (map toLower $ takeExtension url) of
{-タブ-}{-タブ-} ".jpg" -> True
{-タブ-}{-タブ-} ".jpeg" -> True
{-タブ-}{-タブ-} ".gif" -> True
{-タブ-}{-タブ-} ".png" -> True
{-タブ-}{-タブ-} _ -> False
isNotThumb :: String -> Bool
isNotThumb url = not $ (map toLower url) =~ "thumb" :: Bool
0218デフォルトの名無しさん
2010/11/14(日) 18:09:43相対 URL も忘れずに
0219デフォルトの名無しさん
2010/11/14(日) 18:11:42IMG タグ内の SRC だけを調べた方がよくないか
0220デフォルトの名無しさん
2010/11/14(日) 18:18:01相対パス名ガン無視だから、ちゃんと動くのは二次裏だけだと思う
二次裏は、junとかmarとか画像を置いてるサーバを分けてて、全部絶対パス名で書いてるから
0221デフォルトの名無しさん
2010/11/14(日) 20:23:31どなたかご存知ないでしょうか?
0222デフォルトの名無しさん
2010/11/14(日) 20:33:10一昨日までは見てたから、それ以降からだろ
良くある、今までも何度もあった
待ってれば数日で見られるようになる
0223デフォルトの名無しさん
2010/11/14(日) 20:34:350224デフォルトの名無しさん
2010/11/14(日) 21:19:55ありがとうございます
wxHaskellかGtk2HS試したかったのですが、待つことにします
0225デフォルトの名無しさん
2010/11/14(日) 21:31:59どちらも今問題なく hackageDB から落とせるが?
0226Perl忍者 ◆M5ZWRnXOj6
2010/11/14(日) 21:48:510227Perl忍者 ◆M5ZWRnXOj6
2010/11/14(日) 21:56:000228デフォルトの名無しさん
2010/11/15(月) 07:31:160229デフォルトの名無しさん
2010/11/15(月) 20:43:25本やサイトはありませんか。
例えば、末尾再帰の形の関数は引数が正格でなければ効率は上がらないとか。
計算量や必要な(メモリ)空間などの測り方とか。
アルゴリズム系の本やブログなんかで少し紹介されてはいますが、
まとまった情報というのがなかなか見当たりません。
日本語・英語どちらでもかまいません。
0230デフォルトの名無しさん
2010/11/15(月) 21:24:33http://www.slideshare.net/tibbe/highperformance-haskell
http://book.realworldhaskell.org/read/profiling-and-optimization.html
haskell.orgのwikiにも記述があったと思うけど、まだ落ちてるな
0231デフォルトの名無しさん
2010/11/15(月) 21:35:15すいません、紹介しているという言い方が悪かったです。
カタログ化されてるといいなぁと。
(どこもやってなかったら、自分でやってみようかなとは、ちょっと思ってますが)
紹介していただいた前者のページは初めて知りました。
これは、上のスライドを表示しながら、
ページ下の台詞を講演者が喋っていたというイメージですか。
初めの方をちらっと見ましたが、扱ってる話題が多そうなので、
これからじっくり見てみます。
後者の方は原著(ネット)も和訳も読みましたが、浅い感じでした。
なんというか、少なくともこのトピックに関しては
詳細はウェブで、論文で、他書で、公式ドキュメントでという感じでした。
0232デフォルトの名無しさん
2010/11/15(月) 21:43:31忘れてました。
紹介、ありがとうございました。
0233デフォルトの名無しさん
2010/11/16(火) 10:19:020234Perl忍者 ◆M5ZWRnXOj6
2010/11/16(火) 17:44:260235デフォルトの名無しさん
2010/11/17(水) 05:46:15そんなクズみたいな言語は使いたくありません.
http://shootout.alioth.debian.org/
0236デフォルトの名無しさん
2010/11/17(水) 06:28:35リンク貼っとけば勝手に話を膨らませてくれるだろう
まで読んだ
0237デフォルトの名無しさん
2010/11/17(水) 19:29:33あとLuaが意外と上位なんだね
0238デフォルトの名無しさん
2010/11/17(水) 19:31:350239デフォルトの名無しさん
2010/11/17(水) 19:43:42いろんな最適化テクニックを駆使しなければならないとか、
またそのためにソースが見難くなるのなら問題だけど
0240Perl忍者 ◆M5ZWRnXOj6
2010/11/17(水) 21:24:00死んだ方が良いよ
親がかわいそう
0241デフォルトの名無しさん
2010/11/17(水) 23:46:150242デフォルトの名無しさん
2010/11/17(水) 23:55:100243デフォルトの名無しさん
2010/11/18(木) 00:37:04たしかにwww
0244Perl忍者 ◆M5ZWRnXOj6
2010/11/18(木) 22:15:47haskellスレから
誰かいまテレパシーをおくったか?
お前らかわいそうだよ
haskellやって ゴミ掃除やってるレベルだろ
0245デフォルトの名無しさん
2010/11/19(金) 08:40:24Haskellが今より20%くらい速くなると、ほぼJavaの水準になるね
0246デフォルトの名無しさん
2010/11/19(金) 10:01:04Ruby高速化したあの少年連れて来い!
0247デフォルトの名無しさん
2010/11/19(金) 10:03:030248デフォルトの名無しさん
2010/11/19(金) 10:17:200249デフォルトの名無しさん
2010/11/19(金) 10:45:250250デフォルトの名無しさん
2010/11/19(金) 10:55:550251デフォルトの名無しさん
2010/11/19(金) 11:21:25最も新しく発売されたHaskellの書籍は何ですか?
0252デフォルトの名無しさん
2010/11/19(金) 12:37:07Concurrent Haskell
(ISBN-13: 978-6133152977)
たぶん、これが最新だと思う
内容は知らん
0253デフォルトの名無しさん
2010/11/19(金) 12:53:02前スレの末尾までの時点で最新だった奴だと思うんですけどね
0254デフォルトの名無しさん
2010/11/19(金) 18:09:39じゃあこれか
Pearls of Functional Algorithm Design
(ISBN-13: 978-0521513388)
0255デフォルトの名無しさん
2010/11/19(金) 20:30:16ああこれだ!多分これ!
あり^^
0256デフォルトの名無しさん
2010/11/19(金) 20:54:48class Trans t where
fromList :: [a] -> t a
toList :: t a -> [a]
trans :: [a] -> [a]
trans = toList . fromList
ここで Trans 型クラスのインスタンス T1 と T2 があって、
T1 の trans の結果と T2 の trans の結果が
同じなら True 違うなら False を返す関数を作りたいです。
(QuickCheck で確認したい)
しかし、この trans 関数をそのまま使ってそのような関数を作ることは
できないのでしょうか(型シグネチャをどこかに明示して)。
0257デフォルトの名無しさん
2010/11/19(金) 22:03:00無理
そもそもtransの型が曖昧でコンパイル通らない
0258デフォルトの名無しさん
2010/11/19(金) 22:25:34では、
transT1 :: [a] -> [a]
transT1 = t . f
where f = fromList :: [a] -> T1 a
t = toList :: T1 a -> [a]
transT2 :: [a] -> [a]
transT2 = t . f
where f = fromList :: [a] -> T2 a
t = toList :: T2 a -> [a]
などと、T1 T2 それぞれ用の trans 関数を作って、
それらを比較しなければならないのでしょうか。
transT1 と transT2 は T1 や T2 といった型のみが違うだけなのですが、
どうにかしてこの型をパラメータとして指定できる関数は作れないものでしょうか。
0259デフォルトの名無しさん
2010/11/19(金) 22:53:59transの型シグネチャにtが入るように無理矢理にでも変形すればいい
やりかたは複数あるけど、例えば、
{-# LANGUAGE KindSignatures, ScopedTypeVariables #-}
data Wrap (t :: * -> *) = Wrap
trans :: forall a t. Trans t => Wrap t -> [a] -> [a]
trans _ = toList . (fromList :: [a] -> t a)
として、trans (Wrap :: Wrap T1) x yみたいに使う
ちょっとトリックを弄すれば言語拡張なしでも書ける
data (Trans t) => Wrap1 t = Wrap1
trans1 :: Trans t => Wrap1 t -> [a] -> [a]
trans1 w = toList . f w . fromList
where
f :: Wrap1 x -> x b -> x b
f _ = id
0260デフォルトの名無しさん
2010/11/19(金) 23:13:10実現するには、今の Haskell(GHC)では無理矢理やるしか方法が無いんですね。
GHC の拡張機能で、もっとこう特別な構文なんだと一目瞭然な記述で、
スマートに型を伝える手段があるのかなと思ってました。
ソースを見た時に、なぜそのような記述になってるのか
意味を理解しにくくなりそうですね。
今回は QuickCheck 用のソースで、どのようにテストしているか、
その内容を分かりやすくソースで示す必要があるので、
今回は諦めることにしました。
せっかくのアドバイスですが、すいません。
0261デフォルトの名無しさん
2010/11/20(土) 06:57:080262Perl忍者 ◆M5ZWRnXOj6
2010/11/20(土) 09:27:50haskell板のtsuwabukiっていうやつがSkypeにきたぞ
0263Perl忍者 ◆M5ZWRnXOj6
2010/11/20(土) 10:48:49募集要項
1、暇人+1日1回、2chの書き込みができるかた
2、プログラミング経験あり 言語はPerl,Ruby,PHP,Python
3、絵がうまいかた 素材をつくれるかた
4、情報発信が得意なかた
これに当てはまる人ははいれます
主な活動
1、ネットゲームでの全てのゲームにおいての共通ギルドを作り活動
リネージュ、アイラ、マビノギ、アナザーデイなどその他、メンバーがやるゲームすべて
ギルド名はゲームエンペラーズ
2、各ゲームの攻略サイト、wikiなどウェブサービスの作成
3、2chへの書き込み 共有コテ可 自分で好きなコテつくって活動してくれてもあり
4、資本金3000円
Skype: perlkage
http://hibari.2ch.net/test/read.cgi/tech/1284704280/
にご連絡ください
0264デフォルトの名無しさん
2010/11/20(土) 11:50:53Haskellスレと無関係なことばっかじゃん
0265デフォルトの名無しさん
2010/11/20(土) 13:34:03積んでたが、これから読んでみる
書評は2、3ヶ月待ってくれ
途中で色々質問するかもしれん
0266デフォルトの名無しさん
2010/11/20(土) 16:17:58カルトスレは板違いだろうが
0267デフォルトの名無しさん
2010/11/21(日) 11:35:190268Perl忍者 ◆M5ZWRnXOj6
2010/11/21(日) 19:46:38う
0269Perl忍者 ◆M5ZWRnXOj6
2010/11/21(日) 19:53:460270デフォルトの名無しさん
2010/11/21(日) 20:33:39進化論は板違いだろ
しかし、このスレの奴は進化論が好きだな。
0271デフォルトの名無しさん
2010/11/21(日) 20:41:53関連スレ
人工知能を作ろうver0.0.6
http://hibari.2ch.net/test/read.cgi/tech/1263645019/
0272デフォルトの名無しさん
2010/11/22(月) 00:05:42hoge [] = error "hoge: empty list"
hoge = head . tail
せっかくポイントフリーで綺麗に読みやすく書けたと思ったのに、
エラー処理を入れたとたんに仮引数を明示しなければならないなんて
0273デフォルトの名無しさん
2010/11/22(月) 08:22:41忍者はスルーで”カルト”には反応しちゃうんだ....
0274tsuwabuki
2010/11/23(火) 10:27:28アルバイトで生計たててます
0275デフォルトの名無しさん
2010/11/23(火) 16:56:14やはり 15 ページ目で躓く。
真ん中辺りで Jack が
Consider an m x n rectangle and let T(m,n) denote the number of evaluations of f required to search it.
と言っているが、この最後の it は何を指してるんだ?
つまり T(m.n) は何を探すのに必要な f の評価回数なのかが知りたい。
これが分からないから、すぐ下で述べている、
m=0 や n=0 の時に検索の必要がないという意味も、全く分からないんだ。
0276デフォルトの名無しさん
2010/11/23(火) 17:03:270277デフォルトの名無しさん
2010/11/23(火) 17:13:06look insideでそこの直前まで読めるね
search Xの意味は「Xを探す」じゃなくて「Xから何かを探す」
Xは探す対象じゃなくて探索範囲
探す対象はたぶん「f (x,y) = zを満たす(x,y)」じゃね
0278デフォルトの名無しさん
2010/11/23(火) 17:24:41>>277
ありがと
> search Xの意味は「Xを探す」じゃなくて「Xから何かを探す」
マジですか!
今まで生きてきて、X を探すという意味しか無いとずっと思い込んでた。
from の意味が暗黙的に含まれている事もあるのか、目から鱗だ。
英語って奥が深いな・・・
認識を改めてちょっと読み直してみる
0279デフォルトの名無しさん
2010/11/23(火) 17:38:21辞書を引けば分かるけど常にこの意味だよ
「X(物体)を探す」ならsearch for X
0280デフォルトの名無しさん
2010/11/23(火) 17:48:08search a needle in a haystack とか言わないか
0281デフォルトの名無しさん
2010/11/23(火) 17:53:38認識を新たにして読み直してみたが、そうすると今度は直後の
If m=0 or n=0 then there is nothing to search.
が疑問なんだが、もしかしてこれも「探す対象がない」のではなく、
for が無いから「探す範囲がない」と言っているのか?
それでもおかしいな。
例えば m=0 でも、f(0,0) から f(0,z) まで探す必要があって、
(0,0)-(0,z) までが検索範囲になると思ってるんだが、勘違いだろうか。
(正確にはもう少し範囲を狭められるという話題が直前にあったが)
0282デフォルトの名無しさん
2010/11/23(火) 18:10:14m x n rectangleと言ってるんだから、mとnは座標じゃなくてサイズだろ
mかnが0なら、長方形には一点も入らない
>>280
http://www.google.com/search?q=%22search+a+needle+in+a+haystack%22
http://www.google.com/search?q=%22search+for+a+needle+in+a+haystack%22
0283デフォルトの名無しさん
2010/11/23(火) 18:57:50> m x n rectangleと言ってるんだから、mとnは座標じゃなくてサイズだろ
それなら、「探す対象はたぶん「f (x,y) = zを満たす(x,y)」じゃね」と矛盾しないか?
例えば f(0,0)=z だったら、探す対象は (0,0) のはずなんだが、
それは幅 m 高さ n の rectangle の範囲のどこにあるか
と考えた時に「アレ?」って思わない?
なんか、俺が何か大きく勘違いしている気がするんだが・・・
0284デフォルトの名無しさん
2010/11/23(火) 19:20:41探索範囲である長方形を再帰的に分割・縮小していくアルゴリズムで、
その過程で現れるサイズm*nの領域を探索するコストの話をしてるんだから、おかしいところはないはず
0285デフォルトの名無しさん
2010/11/23(火) 21:58:31例えば、f(x,y) が次のような狭義の単純増加関数だったとする。
f(0,0)=5, f(1,0)=6, f(2,0)=7 ...
---------
f(0,1)=6, f(1,2)=7, f(2,3)=8 ...
---------
f(0,2)=7, f(1,2)=8, f(2,2)=9 ...
このような関数で f(x,y)=6 の (x,y) を探すとする。
分割統治で探す範囲を f(0,0)、f(1,0)、f(0,1)、f(1,1) の範囲に絞り込めた時、
Jack の言う m x n rectangle というのは幅 1 高さ 1 ではなく幅 2 高さ 2 なの?
直前の Mary の発言では、検索の範囲は top-left corner (u,v)、
bottom-right corner (r,s) と表現されていて、f(u,v) ではなく
真ん中の f(p,q) から探し始めてはどうかと提案している。
普通こういう場合の幅って r-u や s-v なんじゃないの?
0286デフォルトの名無しさん
2010/11/23(火) 22:01:05ごめん、例のパラメータ値がおかしかった
f(0,0)=5, f(1,0)=6, f(2,0)=7 ...
---------
f(0,1)=6, f(1,1)=7, f(2,1)=8 ...
---------
f(0,2)=7, f(1,2)=8, f(2,2)=9 ...
0287デフォルトの名無しさん
2010/11/27(土) 13:30:58それらにletで一つずつ変数を束縛したいのですが
どんな風に書けば良いでしょうか?
0288デフォルトの名無しさん
2010/11/27(土) 13:39:56ff = let
a = fst f
b = snd f
in
[a,b]
みたいな?
0289デフォルトの名無しさん
2010/11/27(土) 14:08:56g = let (a, b) = f in (aとbを使う式)
で束縛できるでしょ。
0290デフォルトの名無しさん
2010/11/27(土) 21:39:17>>288
なるほど、どうも以前やってた言語のイメージで
「2度呼び出されるのはマズいのでは」と感じてしまって
let tmpList = f
in
let
a = fst tmpList
b = snd tmpList
in ...
みたいなことを考えてしまいました。
でも Haskell の場合、引数が同じなら結果も同じ…と考えれば
そんなことは杞憂かも知れませんね。
>>289
そんな書き方が出来たのですね。
タプルは失念してました。精神的にも良い感じなのでこっちで行こうと思います。
0291デフォルトの名無しさん
2010/11/28(日) 17:56:12仕様上は保障されていないと思うけど、WinGHCiで
Prelude> :m + Debug.Trace
Prelude Debug.Trace> let bar = let {foo = "eval foo" `trace` (1,2); a = fst foo; b = snd foo} in a + b
Prelude Debug.Trace> bar
eval foo
3
となったので、少なくともこの単純な例の場合、ghciではfooは一回しか評価されないみたいね。
しかし、次の場合は二回評価される:
Prelude Debug.Trace> let bar = let {foo x = "eval foo" `trace` (x + 1, x + 2); a = fst $ foo 0; b = snd $ foo 0} in a + b
Prelude Debug.Trace> bar
eval foo
eval foo
3
で、次の例だと一回しか評価されない:
Prelude Debug.Trace> let bar = let {foo x = "eval foo" `trace` (x + 1, x + 2); (a, b) = foo 0} in a + b
Prelude Debug.Trace> bar
eval foo
3
結論としては、「いろいろ考えるのは面倒なので、>>289方式」で良いと思う。
0292デフォルトの名無しさん
2010/11/28(日) 19:05:13それは、書籍なんかでもよく取り上げられるトピックなんだが、
同じ関数を同じ引数値に適用しても、そのつど評価されるんだよ。
同じ引数値だからキャッシングされてるだろうと考えてはいけない。
それはプログラマ自身がキャッシングの仕組みを作る必要があるんだよ。
一般になんていう名前のテクニックだったかな、忘れてしまった。
キャッシングじゃなくて、もっと別の名前があったような気がしたが。
0293デフォルトの名無しさん
2010/11/28(日) 19:18:030294デフォルトの名無しさん
2010/11/28(日) 19:53:53memoize って発音しにくいよな
0295デフォルトの名無しさん
2010/11/28(日) 20:55:38例えば次のプログラムで concat 関数の処理速度を測ったことになる?
time :: IO () -> IO Float
time p = do
st <- getCPUTime
p
et <- getCPUTime
return $ fromIntegral (et - st) / (10^12)
main :: IO ()
main = do
let !l = take 1000 $ repeat (take 1000 $ repeat 1))
t <- time $ do
let !i' = concat l
return ()
putStrLn $ "time : " ++ show t ++ "s"
0296デフォルトの名無しさん
2010/11/28(日) 21:29:05do let !i' = concat l; return ()
は
concat l `seq` return ()
と等価だけど、seqは左辺を最上位の構築子が明示される形(WHNH)までしか簡約しない。この例だと、
concat (take 1000 (repeat (take 1000 $ repeat 1)))
を
1 : 何か
まで評価したらそこで終わってしまう
0297デフォルトの名無しさん
2010/11/28(日) 22:31:31やはりそうか
だからリストの要素数を極端に増やしても 0.0s のままなんだな
let a = concat l
let !b = length a
と
let !b = length l -- (l は concat 済み)
の2つの処理の前後時間の差分を測り、さらにそれらの差分を測れば、
concat の処理速度を測れたと考えていい?
0298100, 103
2010/11/29(月) 01:57:28たしかに、そういうような比較をすれば、ある意味では、concat の処理速度を測れたといってよいと思う。
「ある意味では」というのは、動的なメモリ確保とか、遅延評価のクロージャを処理するコストも測定結果に含まれてしまうけども、ということ。
ただ、オレもそういうことを以前は気にしていたけど、いまはそのような評価はあまり意味がないんじゃないかと思う。
なぜなら、concatの処理速度をそのように計測したところで、実際のアプリケーションではどうせ遅延評価されるわけで、その「concatのコスト」がまるまるアプリケーションのコストになるかどうか分からないから。
もし、特定のアプリケーションで、何かの処理をするまえに必ずconcatの結果をすべて評価しておきたいとかいうことであって、しかもその処理速度が気になるようであれば、
リストのような遅延評価向きのデータ構造とか、concatのような遅延評価前提の関数を使うんじゃなくって、
正格データ型とそのための専用関数を用意するべきじゃないかと思うんだ。
0299298
2010/11/29(月) 02:28:00data List a = Cons !a !(List a) | Nil
deriving Show
concat' :: List (List a) -> List a
concat' Nil = Nil
concat' (Cons Nil tt) = concat' tt
concat' (Cons (Cons h t) tt) = Cons h (concat'' t tt)
concat'' :: List a -> List (List a) -> List a
concat'' Nil tt = concat' tt
concat'' (Cons h t) tt = Cons h (concat'' t tt)
-- テスト用の関数。
-- 次のようにghciなどで評価すると明らかにかかる時間が違う。
-- test 100 100 `seq` ()
-- test 1000 1000 `seq` ()
test :: (Num a) => Int -> Int -> List a
test x y = let {l = take x $ repeat (take y $ repeat 1); f = foldr Cons Nil }in concat' $ f .map f $ l
0300デフォルトの名無しさん
2010/11/29(月) 07:37:15非リアルタイム3Dレンダラーを分割統治法で書いてる。
イメージを縦横いくつかのブロックに分けてそれぞれレンダリングし、
最後にそれらを一つのイメージに合成する。
で、合成する時に、Array ブロックから Array 単体に合成した方が速いのか、
List ブロックから List ブロック 単体か、Array ブロックから List 単体か・・・
その時に使う合成戦略(関数の使い方など)はどれが速いのか・・・
といろいろ実験してた。
> いまはそのような評価はあまり意味がないんじゃないかと思う。
最初 Array で単純に合成しいてたら、合成処理時間だけでけっこうかかってた。
正格に何ミリ秒かかったとかいう数値はそれほど必要ないけど、
レンダリング全体の時間に対する割合くらいはパーセンテージで欲しいんで。
> 必ずconcatの結果をすべて評価しておきたいとかいうことであって
すまん、まだ遅延評価しておかなきゃならないんだ。
合成後もそれを一部テクスチャにして別のレンダリングをしたりするから、
無駄なレンダリング処理を省きたい。
ただ、正格評価用のデータ構造と関数を別に用意しておくという考え方は参考になった。
別の部分の処理で絶対に必要になるから覚えておく、ありがと。
0301デフォルトの名無しさん
2010/11/30(火) 21:19:17次のようなデータ型と、それを使った関数があるとします。
data T = T Int Int
f (T x y) = T (x*2) (y*3)
この関数を次のようにして使った時、
a = T 1 2
b = f (f a)
一度目の f の出力値を作る所から二度目の f の入力の間にかけて、
データ型を被せてすぐに剥がすという無駄なことをしているので、
次のように最適化される嬉しいのですが、
b = T (1 * 2 * 2, 2 * 3 * 3)
特に何もしなくても自動的にこのように最適化されるのでしょうか。
あるいは、書き換え規則(RULES)のような
何かコンパイラへのヒントを与えれば自動的に最適化されるのでしょうか。
それとも、自動的には不可能でしょうか。
コンパイラは GHC 6.12.3 を使用しています。
0302デフォルトの名無しさん
2010/11/30(火) 21:50:32-ddump-simplオプションで最適化済みのGHCの中間コードが見られる
その例のままだと、fが小さい関数だから-Oでインライン化されてb = T 4 18まで最適化される
インライン化できないほど大きいfの場合でも、worker/wrapper変換という最適化がかかるから
すぐ捨てるような中間データは排除してくれることが多い
0303デフォルトの名無しさん
2010/11/30(火) 22:08:59とか、インライン化しない例
0304デフォルトの名無しさん
2010/11/30(火) 22:20:44-ddump-simpl-stats オプションを付けてコンパイルした時、
RuleFired の項目に worker/wrapper が無ければその最適化は効いていない、
つまり中間のデータ型は無駄に構築されているという判断でいいでしょうか。
0305デフォルトの名無しさん
2010/11/30(火) 22:38:33worker/wrapperはRule(書き換え規則)じゃないから関係ないはず
0306デフォルトの名無しさん
2010/11/30(火) 22:45:28最初 -ddump-simpl しても何も出力されなかったから、
とりあえず最適化されたかの目星を付けようとして >>304 と訊きましたが、
今分かりました。
-ddump-simpl の出力を見て、例えば >>301 の例だと、
b が参照している T の中身を辿っていった先が定数になっていれば、
最適化がちゃんと働いたということですね。
0307デフォルトの名無しさん
2010/12/02(木) 15:37:11つまり、
> uArrayToByteString :: UArray Int Word8 -> ByteString
> uArrayToByteString a = pack . elems
という関数を、リストを経由しないように実装したいんですが。
0308デフォルトの名無しさん
2010/12/02(木) 17:18:24uArrayToByteString arr = fst $ unfoldrN size f first
where
(first, last) = bounds arr
size = last - first + 1
f k
| last < k = Nothing
| otherwise = Just (arr ! k, k + 1)
こんなもんかな?
0309デフォルトの名無しさん
2010/12/02(木) 20:52:55import Data.ByteString.Unsafe(unsafePackAddressLen)
import GHC.Prim(byteArrayContents#)
import System.IO.Unsafe(unsafePerformIO)
uArrayToByteString :: UArray Int Word8 -> ByteString
uArrayToByteString arr =
let !(UArray _ _ n barr) = arr
in unsafePerformIO $ unsafePackAddressLen n (byteArrayContents# barr)
0310デフォルトの名無しさん
2010/12/02(木) 21:40:22それは駄目だろ
第一にpinされていないByteArray#に対してbyteArrayContents#を使っているのでGCでbarrが動いたら終了
第二にunsafePackAddressLenは呼び出し側がメモリを管理することを要求するけど、
それを怠っているのでbarrがGCに回収されたら終了
0311309
2010/12/03(金) 23:02:34UArrayとByteStringは内部表現同じっぽいし
ゼロコピーでいけるんじゃね?と思ってでっちあげてみたんだけど、
やっぱりGCでこけるか。
いやまあ、そんな気はしてたんだけど。
0312デフォルトの名無しさん
2010/12/06(月) 08:35:09sum . map (2^) $ [0..9]
sum $ map (2^) $ [0..9]
sum $ map (2^) [0..9]
これらの違い(コスト?)を教えてください。
そもそも$演算子のありがたみが(カッコが減る以外に)思いつかないのですが、
Real World Haskellの索引をみても($)はfmapのところに飛ばされるだけで、
どこに解説してあるのか不明です。
よろしくお願いします。
0313デフォルトの名無しさん
2010/12/06(月) 11:53:39違いはないと思っていい
最適化しない処理系だとコストが微妙に違うけど、sumとmapとenumFromToのコストに比べたら無視できる
>そもそも$演算子のありがたみが(カッコが減る以外に)思いつかないのですが、
基本的にそれだけ
あとは高階関数に($)を渡すとか
0314デフォルトの名無しさん
2010/12/06(月) 15:35:04括弧が減るのは結構ありがたいよ。試しに全部括弧で書いてみるといい。
( はまだその場で書くからいいが、
) はまとめて書くことが多くなるから、数を数えながら書かなきゃならなくなる。
まあエディタの対括弧表示の機能で何とかなるっちゃあなるんだが…
括弧の数で有名なLisp系は実際エディタで何とかしてるみたいだし。
0315デフォルトの名無しさん
2010/12/06(月) 15:49:300316デフォルトの名無しさん
2010/12/06(月) 16:09:500317デフォルトの名無しさん
2010/12/06(月) 16:36:290319312
2010/12/06(月) 19:18:13他人のを読んだときに混乱しそう。
みなさんはどういう規則で$を入れていますか?
それを規約として定義できますか?
>>312
の例だとmap一発ですが、二発三発なめる場合は
合成を使った方がいいようにも見えます。
0320Perl忍者 ◆M5ZWRnXOj6
2010/12/06(月) 20:02:310321デフォルトの名無しさん
2010/12/06(月) 20:04:50- 括弧の代わりに$を使えるならなるべく使う
- 複数行にわたる括弧を消せるときは必ず使う
- 見た目の対称性のために$を使わないことがある(「mappend (f x) (g y)」みたいな場合 )
- 必要のない$は使わない(例えば「f $ g $ x」の右側の$)
- $の左辺に関数合成を置かない(例えば「f . g $ x」)
0322デフォルトの名無しさん
2010/12/06(月) 20:12:36/⌒ ⌒\ ━━┓┃┃
/(  ̄) (_)\ ┃ ━━━━━━━━
/::::::⌒(__人__)⌒:::: \ ┃ ┃┃┃
| ゝ'゚ ≦ 三 ゚。 ゚ ┛
\ 。≧ 三 ==-
-ァ, ≧=- 。
イレ,、 >三 。゚ ・ ゚
≦`Vヾ ヾ ≧
。゚ /。・イハ 、、 `ミ 。 ゚ 。
>>319
そんなに混乱しないと思っているので、基本的に気分次第。
ただ、その気分次第の結果として、最も大きな式(?)の最後の括弧を減らせるかぎりは$を入れ、そうでないときは入れない、という傾向があると思う。
例えば
... = f1 (f2 (f3 a)) というときは
... = f1 $ f2 $ f3 a にしがち。
... = f1 (f2 (f3 a)) b のときは
... = f1 (f2 $ f3 a) b と書けはするけど、それはあまりしない。
0323デフォルトの名無しさん
2010/12/06(月) 20:20:31以外はこっちと同じ方針だ
0324デフォルトの名無しさん
2010/12/06(月) 22:13:41カッコを減らす以外にメリットはないでよ。$なかったらLispみたいになっちゃうから、
俺は結構好き。
0325デフォルトの名無しさん
2010/12/07(火) 10:54:58getNthHogeOfHageInHige
みたいな。
0326デフォルトの名無しさん
2010/12/07(火) 11:19:42x :: D
で、x が B String String であることがわかっているときに、
f (case x of B s _ -> s)
というのをもっと簡便に書くにはどうしたらいいでしょう?
0327デフォルトの名無しさん
2010/12/07(火) 12:54:03一概には言えないが、関数型言語の関数(function)は、
手続き型言語の手続き(procedure)とは違って静的なものなので、
たいていは動詞ではなく名詞を使うように頭を切り換えると良い場合が多い。
だから、「get」「put」「set」「conv(ert)」などのような動詞が
なるべくなら接頭辞として付かないような方向で考える。
また、修飾語句はできる限り引数の型で表した方がスッキリする。
例えば「n番目の」というのは標準ライブラリを見ても関数名には無いと思う。
同じ役割の関数で番号指定できるものとできないものが有るなら、
(必要なら)私なら関数名の後ろにNを付けるか付けないかで区別するが、
その前にそもそも番号指定版だけで済ませられないか考える。
「〜の中の」とか「〜の」というのも、まず引数の型で表すことを考える。
「〜」に当たるものが色々あるのなら、それらをひとつの型クラスで表し、
その型クラスに対する「の中の」関数だけの状態にして、
関数名には「〜の中の」という言葉は入れないようにする事を考える。
「〜の中にある〜の中の」というように入れ子状に続くのは論外。
この場合は関数をいくつかに分けて、ひとつの関数で「〜の中の」は
多くても一つだけの状態にするように考える。
ただ、分けたそれぞれの関数が独立では使われず、
いつも「〜の中にある〜の中の」という状態で使われる場合は、
関数を分けずにひとつの関数で表して、
関数名としては一番外側の「〜の中の」だけを表した方がいい。
しかしこの場合、そもそも設計がおかしいことの方が多いが。
0328デフォルトの名無しさん
2010/12/07(火) 13:06:09data D = A Int Int | B { foo :: String, bar :: String }
f (foo x)
0330デフォルトの名無しさん
2010/12/07(火) 14:28:28大変おもしろく読んだけれど、ここは気にいらない。
>その前にそもそも番号指定版だけで済ませられないか
常に要求された通り、または、心に浮かんだ通り、
定義するのが基本だと思う。
0331327
2010/12/07(火) 18:11:06そりゃ考え方は人それぞれだ。
ひとの考え方と自分の考え方の何がどのように違うのか、
何故違うのか、互いの色んなケースでのメリット・デメリットは何か、
色々比較した上でそっちの方がいいと思うのならそれでいいんじゃないか。
0332327
2010/12/07(火) 18:54:04「指定しない版だけ」を作る方針の方がいいかもしれない。
順序付き集合を返す「番号を指定しない版の関数 hoges」と、
「何かの順序付き集合から特定番号の要素のみを返す関数 pick」に分ける。
例えば3番目の hoge が欲しかったら pick 3 hoges と記述する。
そうすると、pick 関数は他にも流用できるし、関数名を短くできる。
また、式を右から読んでいって何を表す式なのか、
比較的分かりやすいんじゃないかな。
これなら、番号を指定する必要がない時は hoges だけでいいから、
「常に要求された通り、または、心に浮かんだ通り、定義」できると思う。
0333デフォルトの名無しさん
2010/12/07(火) 20:07:15これ良くないの!?
寧ろ積極的にこう書き換えてた!
0334デフォルトの名無しさん
2010/12/07(火) 20:45:59どの書き方がわかりやすいかは一概に言えない
0335デフォルトの名無しさん
2010/12/07(火) 20:47:07どの状況でどれを使っても大差ないよ
0336デフォルトの名無しさん
2010/12/07(火) 20:51:040337デフォルトの名無しさん
2010/12/07(火) 21:36:11単なる好み(カッコよく言えば哲学)の問題だ。
私の場合はその書き方は気持ち良くないと感じる。
どちらかと言えば f (g x) の方が気持ちいい。
なぜなら、関数 f が適用するモノが分かりやすいと感じるから。
でも、その差は微々たるものだ。
そもそも、「分かりやすさ」というもの自体が個人の物差しであって、
その物差しをチーム内で(たいていは強引に)揃えるのが「コーディング規則」だ。
個人でプログラムしてるのなら、好きにすればとしか言いようがない。
0338デフォルトの名無しさん
2010/12/07(火) 22:12:49は自分なら、あとでポイントフリーにしたいけど、
わかりやすさのためにまず変数を書いておくときに使うかな。
書き終わったらこの形は残らない。
0339デフォルトの名無しさん
2010/12/07(火) 22:46:56後でポイントフリーにするのはどうして?
仮引数が残っているよりも、ポイントフリーの方が
分かりやすかったり、見やすかったりするから?
もしそうなら、それは「わかりやすさのためにまず変数を書いておくとき」
の場合の「わかりやすさ」とは違う質のもの?
0340デフォルトの名無しさん
2010/12/07(火) 23:00:350341デフォルトの名無しさん
2010/12/08(水) 00:57:11書くときと読むときのわかりやすさが違うのかも。
書くときは仮引数xをデータとしてそれへの関数適用で考えて、
読むときは型宣言を手掛かりとしつつ右から左へ合成された関数の流れを見る。
だから、完成して型検査を通ったら、読みやすいようにポイントフリーにして
書き終わる。(左辺のxと、"$ x"を削除する)
はじめからポイントフリースタイルで書くのはちょっと難しい。
0342デフォルトの名無しさん
2010/12/08(水) 07:30:50> 読むときは型宣言を手掛かりとしつつ右から左へ合成された関数の流れを見る。
ポイントフリースタイルだからこその分かりやすさというのが、
この説明ではまだよく分かんないな。
これなら最後の $ x が有っても無くても大して変わらなくない?
> はじめからポイントフリースタイルで書くのはちょっと難しい。
つまり逆で、最後にわざわざポイントフリーにしなくてもいいんじゃない?
0343デフォルトの名無しさん
2010/12/08(水) 07:53:410344342
2010/12/08(水) 07:56:31それは初めからポイントフリーで考えている時だけ。
関数作成を考え始める時点で、どのような役割の関数か、
つまり「何から何への写像」を作ろうとしているのかは分かってる。
これがメイン引数となる。
それを実現するのに必要な情報、サブ引数も洗い出せば分かる。
写像の形を元に、どの関数をメインに使って実現させるのか方針が立てられる。
(map なのか、filter なのか、その組み合わせなのか、既存の自作関数かなど)
この時点で自然にポイントフリーで考えてる。
(ポイントフリーにできない場合も、ごく自然に非ポイントフリーで考えてる)
あとは、サブ引数を使って肉付けし、ソースを記述する時点では、
ポイントフリーになってる。
あとからポイントフリーにリファクタリングするケースはほとんどない。
そういうケースは自分の設計力の無さに多少落ち込む。
0345デフォルトの名無しさん
2010/12/08(水) 07:59:22http://www.haskell.org/haskellwiki/Programming_guidelines#Application_notation
ここでもオレらみたいな話をしている:
http://stackoverflow.com/questions/1983047/good-haskell-coding-standards
0346デフォルトの名無しさん
2010/12/08(水) 09:38:200347デフォルトの名無しさん
2010/12/08(水) 09:51:590348デフォルトの名無しさん
2010/12/08(水) 13:07:120349デフォルトの名無しさん
2010/12/08(水) 13:25:050350デフォルトの名無しさん
2010/12/09(木) 00:05:49自然にポイントフリーで考えてるってのは「関数型脳」が既に身についているってことでしょ。
俺も初めは>>342みたいに、関数を書いた後からポイントフリーに
直してみるってことをやってたよ。
手続き型言語に慣れた脳味噌には、初めから関数合成で考えるのはちと難しいんだよね。
だから、まずは手続き的に「値を順番に変形させていく過程」として捉えて関数を書いてから
後からポイントフリーにすることで、改めて関数合成として捉え直してみるっていう感じだな。
そういう修行wを通じて、段々と「自然にポイントフリーで考え」られる脳味噌が
できていくんじゃないかな。っつか、俺の場合はそう。
0351デフォルトの名無しさん
2010/12/09(木) 01:59:40↓
念のためうぷ(´・ω・`)まわいが重要
グーグル検索
↓
やらなくてもやられるし 日本語以外話せないし
テレビやネットで説明
0352デフォルトの名無しさん
2010/12/09(木) 07:32:50そういう関数型と手続き型を比較しつつ、
関数型の思考法を徹底的に解説する本があれば面白そうだ。
関数型らしさとは何か、と複数の著名人にインタビューした記事とか。
「Introduction to Functional Programming(関数プログラミング)」や
「Fun of Programming(関数プログラミングの楽しみ)」などは
そういうのとはちょっと違う感じだった。
(後者はわりと近いが)
0353デフォルトの名無しさん
2010/12/09(木) 11:46:32俺も未だに手続き脳なんで、すごく解る。
「自然に書く」と、およそポイントフリーには向かない設計になってるんよね。
0354デフォルトの名無しさん
2010/12/09(木) 12:06:03ストリームを意識せよ
0355デフォルトの名無しさん
2010/12/09(木) 12:12:58Haskell 98 Reportの3.11 リスト内包表記で、
[ x | xs <- [ [(1,2),(3,4)], [(5,4),(3,2)] ], (3,x) <- xs ]
が [4,2] になるという例が載っています。
で、この「3」を変数として与えられるようにしようと、
(\y -> [ x | xs <- [ [(1,2),(3,4)], [(5,4),(3,2)] ], (y,x) <- xs ]) 3
とすると、内包表記内でyのスコープが別にできてしまい、
結果が [2,4,4,2] になってしまいます。
とりあえず、ガードをつけて、
(\y -> [ x | xs <- [ [(1,2),(3,4)], [(5,4),(3,2)] ], (z,x) <- xs, z==y ]) 3
とすれば、望みのことができますが、こうするしかないものなのでしょうか?
0356デフォルトの名無しさん
2010/12/09(木) 12:20:35なんで y にしたいの
0357デフォルトの名無しさん
2010/12/09(木) 12:24:10そうするしかない
内包表記に限らず動的にパターンを作る方法はない
0358デフォルトの名無しさん
2010/12/09(木) 12:42:40えっと、意味がよくわかりません。
>>357
ありがとうございます。そういうものなのですね。
パターンは静的にしか書けないという規則だと思えば、すっきりしました。
0359俺用謹言集
2010/12/09(木) 16:44:360360デフォルトの名無しさん
2010/12/09(木) 18:50:050361デフォルトの名無しさん
2010/12/09(木) 23:02:360363デフォルトの名無しさん
2010/12/10(金) 22:28:090364デフォルトの名無しさん
2010/12/11(土) 14:17:44私が心に留めているのは次の言葉。
「時間を空間に」
自分でこれに気づいた時は「俺すげー」と革命が起きた感じだった。
後で調べてみると、誰もが当たり前のように考えた事だと分かったが、
これが Haskell の本質だと確信を得た感じで逆に嬉しかったな。
0365デフォルトの名無しさん
2010/12/11(土) 21:40:140366デフォルトの名無しさん
2010/12/11(土) 22:11:27たとえば、2つの計算 A と B が有るとする。
A を計算し、その結果が x だったらそれを使用し、
もし結果が y だったら B の計算結果を使用したい。
他の言語なら、A の後で B を計算する様に、逐次的に見える様に記述するが、
Haskell なら A と B を同時に計算する様に、宣言的に見える様に記述する。
それはリストに羅列されていたり、演算子で結合されていたりと、形は様々だ。
で、A と B のどちらが必要になるかはたいてい別のところに記述する。
B が不要なら実際には計算されない。
つまり、時間的な流れに沿った計算を空間に広げて「一望できる」ようにする。
これが遅延評価の為せる業であり、宣言的に記述できる Haskell の特徴だ。
これは一例だが、時間の流れを空間の広がりに換える考え方は、
Haskell プログラムの至る所で役に立つ。
0367デフォルトの名無しさん
2010/12/11(土) 23:02:510368デフォルトの名無しさん
2010/12/11(土) 23:04:04逐次的に見えるっていうか現実に逐次的だよね。
現実に沿った計算を、非現実的観点で一望することにどういう意味があるの?
0369デフォルトの名無しさん
2010/12/11(土) 23:31:34> 逐次的に見えるっていうか現実に逐次的だよね。
ちょっと違う。
現実のものを逐次的視点で捉えるか全体を一度に捉えるかの違いであり、
どちらが分かりやすいかは時と場合と「好み」による。
Haskell は後者の様に捉えた方が分かりやすい問題を綺麗に記述できる。
また、「一見」前者の様に捉えた方が分かりやすかった問題を、
後者の様に捉え直すことで、Haskell で扱いやすくする。
> 現実に沿った計算を、非現実的観点で一望することにどういう意味があるの?
計算Aはどのようにするのか、ではなく、計算Aとは何か、
という構造が分かりやすく(見やすく)なる。
(繰り返すが、後者の方を好む人にとって分りやすくなる)
例えばパーサーなら、X := A | B というバッカス記法をそのまま記述できる。
Aを読み取って失敗したらBを読み取ったものがXだと逐次的に捉えるのと、
XはAまたはBだと全体を一度に捉える違いだが、後者の方が一望できて分かりやすい。
分割統治も全体を一度に捉えた方が比較的分りやすい例だと私は思う。
0370デフォルトの名無しさん
2010/12/11(土) 23:32:30例が悪いのか?
0371デフォルトの名無しさん
2010/12/11(土) 23:38:31データフローや並列計算の話をしたら喜ばれそうだけど
Haskellの本質とやらはそっち方向にはなさそうだよ
0372デフォルトの名無しさん
2010/12/11(土) 23:38:580373デフォルトの名無しさん
2010/12/12(日) 00:00:04私も Haskell 歴はまだ1年とちょっとでかなり浅いから、
みんなを黙らせる良い例を挙げられないのが悔しいが・・・
時間と空間という言い方がまずかったのかな。
相対論的な意味での時間と空間の置換という意味では決してないんだ。
ではこう言ってはどうだ?
「動を静に」
手続き型言語なら時間軸に並べられた計算を動的に捉えて書くけど、
Haskell ならそれらの関係性を静的に一度に捉えた方が扱いやすくないか?
FRP による GUI ライブラリなんか正にそんな感じに捉えてるような気がするんだが。
0374デフォルトの名無しさん
2010/12/12(日) 00:04:48それなら良く分かる
手続き的か宣言的か、という奴だね
0375デフォルトの名無しさん
2010/12/12(日) 00:06:38これなら感覚としてはまあ分かる
でも金言って程ではないかな
0376デフォルトの名無しさん
2010/12/12(日) 00:13:09>>375
そうなのか
ただ、やっぱり私の中では時間的に考え方を空間的に捉え直す方が
しっくり来るというか、「動を静に」よりももう少し意味が広くて、
関数型の中でも遅延評価デフォの Haskell らしい感じが秘められてると思うんだが。
宣言的なら他の関数型でも普通にやってるし・・・
まぁいいや。
あまり盛り上がりそうな話でもなかったと言うことで、消えます
0377デフォルトの名無しさん
2010/12/12(日) 00:37:37それを、一言でいうと「数学と同じ」だと思うんだよね。だから、誰もわざわざ指摘しないというか。
0378デフォルトの名無しさん
2010/12/12(日) 00:58:130379デフォルトの名無しさん
2010/12/12(日) 01:02:52なんでそういう大事なことを入門書では教えてくれないんだろうな。
入門するには頭を切り換える必要があると著者は分ってるはずだが、
何を頼りにどう切り替えるのか、本質は何かを解説しないで、
文法やケーススタディばかり解説する。
0380デフォルトの名無しさん
2010/12/12(日) 01:25:150381デフォルトの名無しさん
2010/12/12(日) 01:32:34いまいち意味が分らんな
教育と言えば、今の Haskell の入門書って、微分積分を使わずに
運動方程式の計算だけを教えて意味を教えない高校物理みたいな、
なんとも言えない気持ち悪さを感じる
0382デフォルトの名無しさん
2010/12/12(日) 01:36:310383デフォルトの名無しさん
2010/12/12(日) 01:42:21こういう話が嫌なら、Haskell ブログラムのネタを振ってくれ
今は特に話題がないからダベってるだけだ
0384デフォルトの名無しさん
2010/12/12(日) 01:49:030385デフォルトの名無しさん
2010/12/12(日) 01:58:08STモナドは時間の流れを意識せずには書けないけれど、極めて純粋だよね
静なんだけど動なモナドだよね
この流れ的にはどうなの?
0386デフォルトの名無しさん
2010/12/12(日) 02:06:16俺が知るかよ
STモナドが気持ちいいかどうかと訊かれれば、俺は気持ちよくはないな
避けて通れるなら避けたいところだ
STモナドを使うと気持ちよく表現できるアルゴリズムとか未だ知らんし
なにかある?
0387デフォルトの名無しさん
2010/12/12(日) 02:07:49クイックソートとかQR分解とか
0388デフォルトの名無しさん
2010/12/12(日) 02:12:18「虚数の情緒」みたいな、著者が可能な限り妥協しない、
分厚いが本質を丁寧に述べて Haskell の楽しさを思う存分語る、
そんな入門書があってもいいと思うな。
0389デフォルトの名無しさん
2010/12/12(日) 03:03:46「embedding-projection pair」というものが既知のものとして出てきたのですが、
どういったものか誰か知ってませんか。
どうも、embedding-projection でペアにするのは関数で、
それをこの論文では関数ではなく Arrow をペアにするアイデアを使ってるみたいなんです。
なんとなく、embedding-projection pair は、
a -> b という型の関数とその逆変換の b -> a という型の関数をペアで持つ、
という感じを受けたのですが、合ってるでしょうか。
これは元々どのような問題解決の文脈で出てきたものか、
知ってる人はいないでしょうか。
ちなみに、embedding-projection pair の参考文献は
R. Hinze and S. Peyton Jones. Derivable type classes. In G. Hutton,
editor, Proceedings of the 2000 ACM SIGPLAN Haskell Workshop,
volume 41.1 of Electronic Notes in Theoretical Computer Science.
Elsevier Science, Aug. 2001. The preliminary proceedings appeared
as a University of Nottingham technical report.
らしいので、ACM Digital Library 内を探しましたが、見つけられないです。
0390デフォルトの名無しさん
2010/12/12(日) 06:50:31手続き的に書くと
1. 入力を促すメッセージを表示
2. キーボードから文字列を入力
3. 特定の文字列or文字列終端が入力されると終了
4. 入力された文字列に関数を適用
5. 適用した結果を表示
6. 最初に戻ってループ
な感じのプログラムなんですが…
0391デフォルトの名無しさん
2010/12/12(日) 09:22:30とりあえず書いてみた
module Main where
main = loop f
f :: String -> Maybe String
f ":q" = Nothing
f s = Just $ "input: " ++ s ++ "\n"
loop :: (String -> Maybe String) -> IO ()
loop f = do
input <- getLine
case f input of
Just output -> putStr output >> loop f
Nothing -> return ()
0392391
2010/12/12(日) 10:14:29仕様に完全には一致していなかったので書き直し:
module Main where
import System.IO
main = do
hSetBuffering stdout $ BlockBuffering Nothing
loop "input any... " f
f :: String -> Maybe String
f ":q" = Nothing
f s = Just $ "your input: " ++ s ++ "\n"
loop :: String -> (String -> Maybe String) -> IO ()
loop msg f = do
hPutStr stdout msg
hFlush stdout
input <- getLine'
case input >>= f of
Just output -> putStr output >> loop msg f
Nothing -> return ()
getLine' :: IO (Maybe String)
getLine' = do
bool <- isEOF
if bool
then return Nothing
else Just `fmap` getLine
0393デフォルトの名無しさん
2010/12/12(日) 10:50:18http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm
0394デフォルトの名無しさん
2010/12/12(日) 11:51:470395デフォルトの名無しさん
2010/12/12(日) 11:58:42上手く言えないけど、無駄に話を難しくしてる気がする。
「時間を空間」にの「空間」の意味が曖昧でよくわからない。
っていうかそれHaskellの本質ってより、ただ高階関数と条件分岐を
組み合わせただけなんじゃ...?
0396395
2010/12/12(日) 12:05:04プログラミングHaskellは高校物理っぽくないという点で
結構いいと思うんだけど、どうよ?
>>366
ちゃんと続き読んでなかった。動を静にか。それは結構納得できるかも。
0397デフォルトの名無しさん
2010/12/12(日) 12:42:54なるほど
「Proceedings of the 2000」や
「Proceedings of the 2000 ACM SIGPLAN Haskell Workshop」をキーワードに
ググってたから見つからなかったのですね。
ありがとうございます、助かりました。
0398デフォルトの名無しさん
2010/12/12(日) 13:00:170399デフォルトの名無しさん
2010/12/12(日) 13:51:42いいと思うよ
0400デフォルトの名無しさん
2010/12/12(日) 14:27:00> 「時間を空間」にの「空間」の意味が曖昧でよくわからない。
空間は、結果的にはソースコード上の横方向の広がりだ。
縦方向の広がりが時間と考えてくれていい。
たとえば2つの図形A、Bがあり、これらを表示するアプリを作るんだが、
デフォルトではAの座標はBの座標系で表現されている。
しかし、ユーザーのメニューでの選択などで逆の場合も起こる。
つまりBをAの座標系で表現した方が扱いやすくなる。
時間軸に沿うなら、初めはAをBにする座標変換行列を計算して保存しておき、
メニューを選択した時点でBをAにする座標変換行列を計算して置き換えると考える。
そうではなく、AとBの関係性をソースコード上で一望できるように
空間的(ソースコード上の横方向の広がりに換えて)に考えるなら、
初めからAからBへの座標変換行列とBからAへの座標変換行列の
両方を計算してタプルやリストなどに格納しておくような記述をする。
図形(座標系)が複数合っても同じ。
互いの変換行列を最初に計算して、関係性をグラフで表しておく。
後で必要になった時にグラフのノードを辿って行列をかけ算していく。
これでイメージが少しでも伝わらなかったら、たぶん私の考え方が
どこか間違ってると思うので、しばらく頭を冷やす。
0401デフォルトの名無しさん
2010/12/12(日) 14:37:59HTMLの実体参照。
つまり、「 」を入れる。
0402デフォルトの名無しさん
2010/12/12(日) 14:56:48「時間を空間に」というと、破壊的に置き換えるイメージが伝わる
でも「時間だけでなく空間も」というと、両方を認めるマルチパラダイムになる
0403デフォルトの名無しさん
2010/12/12(日) 15:01:410404395
2010/12/12(日) 15:04:45ふーん。やっぱり何かおかしいと思うよ。わかりやすくするために例を挙げるのに、
座標変換やらなんやらが出てくるのか。
結果的にソースコードの横が空間で縦が時間だと言うけれど、
hoge >> huga
と
do hoge
huga
が同じ意味になるという点についてはどうなんだろう。
しかも手続き言語でも、座標変換のルーチンは関数で定義するわけだから、
はじめから変換行列は(記述上では)計算済みということになるんじゃないの?
「動を静に」が納得できるのは、手続き言語では状態の変化の様子を
そのまま記述するのに対して、Haskellその他では、
ある状態が別の状態に変化するときの「間」を記述することが多いから。
状態そのものは「動」だけど、状態と状態の「間」は静だよね。
0405395
2010/12/12(日) 15:38:39>>369を読んでちょっと言いたいことがわかったかも。
モナドのことを言ってるんだな。そのパーサーの例だけど、パーサーは処理の観点から
見れば、逐次的なものだけど、文法を定義したい人間としては静的に捉えたい。
人間から見ると逐次的な部分は重要じゃないから、逐次的な部分をバインド演算子に中に
隠すことができるモナドはとても強力。
でも、それ捉え方の問題じゃなくて、言語の抽象化能力のことだと思う。
オブジェクト指向では文法の問題もあって、パーサーを静的っぽく記述するのは難しい。
少なくとも「時間を「空間に」」の言い方は全く良くない。「空間に」変えるのではなく、
時間的な問題を「隠蔽する」、と言う方が正しいと思った。
0406デフォルトの名無しさん
2010/12/12(日) 17:33:470407デフォルトの名無しさん
2010/12/12(日) 17:54:570408デフォルトの名無しさん
2010/12/12(日) 17:56:06手段を使えるようにするのが研究
0409デフォルトの名無しさん
2010/12/12(日) 18:03:170410デフォルトの名無しさん
2010/12/12(日) 18:05:480411デフォルトの名無しさん
2010/12/12(日) 21:26:38ある。断じてある。
0412デフォルトの名無しさん
2010/12/12(日) 23:56:16欲しい!
0413390
2010/12/13(月) 00:44:43ありがとうございます。とりあえず対話的に動くところを確認しました。
やっぱり元があまりに手続き的だけに、若干ややこしくはなりそうですね。
あとは出てきた1つ1つの要素を見ていって、詳しく見ていこうと思います。
0414Perl忍者 ◆M5ZWRnXOj6
2010/12/13(月) 21:21:32ごみめら
0415デフォルトの名無しさん
2010/12/13(月) 21:55:51ちゅっちゅ
0416デフォルトの名無しさん
2010/12/14(火) 00:21:55> やっぱり元があまりに手続き的だけに、若干ややこしくはなりそうですね。
んー… 手続き的な処理は、例外的な処理を詰め込んでいくと、いっきにややこしくなる。
>>390の仕様だと、「3. 特定の文字列or文字列終端が入力されると終了」の部分。
こういうのは、自分が使うだけのプログラムなら、べつにわざわざ書く必要はなくって、終わればプロセスをKILLしちゃえば良い、例外がスローされたらそのまま死ねばよい、という考え方もできる。
そういうふうに割り切れば、プログラムはすごく単純になる。
でも、そういうときも綺麗にかっこよく終わりたいとなれば、面倒なことになる。
これは手続き型だろうと、関数型だろうと、どんな言語でも同じではなかろうか。
0418デフォルトの名無しさん
2010/12/14(火) 08:27:170419デフォルトの名無しさん
2010/12/14(火) 13:36:21xmonadもじゃない?
0420デフォルトの名無しさん
2010/12/15(水) 11:59:16HaskellでFlash書けたら嬉しくね?
0421デフォルトの名無しさん
2010/12/15(水) 12:13:040422デフォルトの名無しさん
2010/12/15(水) 12:14:430423デフォルトの名無しさん
2010/12/15(水) 19:08:01こういうことをやってる人もいる
http://hackage.haskell.org/package/swf-1.0.1
0424420
2010/12/15(水) 20:41:56スティーブ・ジョブズ乙
でも、たしかに、HTML5も魅力的。
>>423
やはり、オレが思いつく程度のことは、すでに手を付けている人がいるんだな。
0425Perl忍者 ◆M5ZWRnXOj6
2010/12/15(水) 22:40:21ここのスレよく脱線してますね
0426デフォルトの名無しさん
2010/12/15(水) 22:44:020427Perl忍者 ◆M5ZWRnXOj6
2010/12/15(水) 22:52:10てめえみたいなやつは自殺しろ
0428デフォルトの名無しさん
2010/12/15(水) 23:18:060429Perl忍者 ◆M5ZWRnXOj6
2010/12/15(水) 23:34:260430Perl忍者 ◆M5ZWRnXOj6
2010/12/15(水) 23:36:38* 名前 tsuwabuki
* 自己紹介 pi-calculus, CSP, lambda-calculus, haskell, erlang, HTML5, P2P, 料理作り(プリン・パンなど), 筍, 紅茶, サーバ運用, 自作サーバ, 電子書籍, iPhone, Android, Arduino, 変形合体ロボット, gumonji
http://twitter.com/iasija
かすみてえだな
420 426 428はtsuwabukiだろうね
てめえは低レベルだからさっさとしね
0431Perl忍者 ◆M5ZWRnXOj6
2010/12/15(水) 23:41:55ごみめら
ここのスレも荒れるしな
0432デフォルトの名無しさん
2010/12/15(水) 23:50:50な言語要素がseq a bなのはなぜ
なのでしょうか。force aがあって、
その場で、ただちにaを簡約するとなっ
いれば、seqよりも一般的と思う。
0433デフォルトの名無しさん
2010/12/15(水) 23:56:130434デフォルトの名無しさん
2010/12/16(木) 00:39:02と書くと、xに束縛されるのは、
この式の評価結果(42という整数
としよう)ではなく、簡約グラフ
と呼ばれる一種の計算手順であると
入門者向けの説明ではなっている。
また、この式が42に簡約されるのは、
xまたはxを含む式をファイルに書き
だすときである。
結果、つまり、ファイルに42が書かれる
ことは間違いない。しかし、簡約グラフ
が蓄積されるかもしれない。そこで、
簡約グラフの形成後、ただちにこれを
42に簡約する指示を与える術がプログラマ
に与えることを考え、これにforceという
名前をつけたのである。
seq a bはこの弱いバージョンで、bよりもa
が先に簡約されることしか指示してない。
0435デフォルトの名無しさん
2010/12/16(木) 01:31:05その force a がいつ評価されるのか、ということを考えなくてはいけない。
例えば、
f a = let b = force a in 10
という関数の場合、そのforce aが決して評価されない結果、aも評価されない。
逆に、
f a = let b = force a in b
となっていれば、force a が評価される結果、aも評価されるけど、それなら
f a = let b = a in b
と書いても同じこと。
0436デフォルトの名無しさん
2010/12/16(木) 02:47:05haskell普段あんま書いてないから文法的に怪しいが
もしそのforceがあったとしても
somefunc (force a) (force b)
がa→bの順に実行されるかは決まらない
(通常は遅延評価されるので文脈次第)
なので実行順序が決まらないその1引数のインタフェースでは役に立たない
0437デフォルトの名無しさん
2010/12/16(木) 09:12:09そういうことがしたいならseqで十分
let x = 式1 in 式2
を
let x = 式1 in seq x 式2
にすればいい
0438デフォルトの名無しさん
2010/12/16(木) 09:57:52http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html
0439デフォルトの名無しさん
2010/12/16(木) 19:43:57http://www.haskell.org/haskellwiki/Lambdabot
0440デフォルトの名無しさん
2010/12/16(木) 20:01:15かわいいね。実にかわいい。すごくかわいい。とってもかわいい。
0441デフォルトの名無しさん
2010/12/16(木) 20:33:35日本的な「萌え」にする必要はないと思うんだが、もう少しどうにかならなかったのかと小一時間…
0442デフォルトの名無しさん
2010/12/16(木) 21:56:350443デフォルトの名無しさん
2010/12/16(木) 22:21:170444デフォルトの名無しさん
2010/12/16(木) 23:23:46ttp://book.realworldhaskell.org/read/concurrent-and-multicore-programming.html#id676390
0445デフォルトの名無しさん
2010/12/16(木) 23:26:15無意識に左から評価すると考えてました。
そのためのseqなのですね。大変よくわかりました。
>>437
ありがとうございます。
表面的な使い方としては、理解できましたが、
seqでの等価表現のところがまだ理解しきれません。
>>442
geekはhaskellに似つかわしくないなぁ。
もっとクールビューティなのがいい。
0446デフォルトの名無しさん
2010/12/16(木) 23:34:510447デフォルトの名無しさん
2010/12/17(金) 03:06:01すごく残念だ
0448デフォルトの名無しさん
2010/12/17(金) 21:25:18hackage にある encoding ライブラリをインストールしようとしましたがエラーが出ます。
以下の方法を試みました。
1. hackage から encoding-0.6.3.tar.gz をダウンロードし展開する [c:\encoding]。
2. ネット上から nl_types.h と langinfo.h をダウンロードし、
encodingフォルダに入れる。
3. cabal install --extra-include-dirs=c:\encoding --extra-lib-dirs=c:\encoding
メッセージは次の通り
-------------------
Building encoding-0.6.3...
...
[ 6 of 65] Compiling Data.Encoding.ByteSource ( Data\Encoding\ByteSource.hs, dis
t\build\Data\Encoding\ByteSource.o )
Data\Encoding\ByteSource.hs:149:17:
Not in scope: data constructor `State'
cabal: Error: some packages failed to install:
encoding-0.6.3 failed during the building phase. The exception was:
ExitFailure 1
-------------------
こういう場合、未定義データ構築子 State はどうすればいいんでしょうか。
<環境>
Windows 7
Haskell Platform 2010.2.0.0
(ghc 6.12.3
cabal-install 0.8.2
Cabal library 1.8.0.6)
0449デフォルトの名無しさん
2010/12/18(土) 09:50:370450デフォルトの名無しさん
2010/12/18(土) 10:11:06それ多分mtl-2.0でStateモナドがStateT Identityの別名になったので壊れたんだな
encodingの作者に連絡して直してもらうべき
応急手当としてはencodingの.cabalファイルのmtlへの依存を<2.0に限定するとか
0451デフォルトの名無しさん
2010/12/18(土) 10:19:37nl_langinfo呼んでるけど
0452デフォルトの名無しさん
2010/12/18(土) 12:17:110453デフォルトの名無しさん
2010/12/18(土) 14:07:47State なんて自分で直接使うことは滅多にないので、
あれ? あったはずだがと思ってましたが、定義が変更されてたのですね。
拙い英語でバグレポートを出しておきました(ちゃんと伝わってるといいのですが)。
>>451
さぁ? 一応 cabal configure は通ったのでイケると思った矢先のエラーでした。
>>452
text ライブラリを使ってみたら、いともあっさりと目的が達成されました。
こちらでやることにします。
みなさん、ありがとうございました。
0454デフォルトの名無しさん
2010/12/18(土) 14:17:15ほらよ、童貞ども
0455デフォルトの名無しさん
2010/12/18(土) 19:43:45> ほらよ、童貞ども
純粋なのは良いことさ。
0456デフォルトの名無しさん
2010/12/19(日) 02:10:34http://www.kotha.net/ghcguide_ja/latest/hsc2hs.html
-----
#enum 型, 構築子, 値, 値, ...
#constを使った複数の定義の代替となる略記法。
それぞれの値はCの整定数(例えば列挙値)の名前である。
この名前は、アンダースコアの次の文字を大文字にし、それ以外を小文字にし、
アンダースコアを取り去ることで、Haskellの名前として使われる。
-----
とあるんだけど、これって 例えば #{enum CInt, , AAA_BBB = 0} とやったら、
aAAbBB = 0 に自動的に変換してくれるんじゃないの?
やってみたら、AAA_BBB = 0 に変換されたんだけど、
もしかして説明には自分で名前を haskell 風に変換する「方針」が書かれてるだけ?
あと、C 言語のヘッダに書かれてる enum 型は自動では変換されない?
0457デフォルトの名無しさん
2010/12/19(日) 10:18:50=で値を明示する形式だと変換しないよ(最初からHaskellでの名前だから変換する必要がない)
値を明示しない場合は、Cの識別子として値を取得した後に
Haskellの識別子として同じものを定義するので変換が必要
>あと、C 言語のヘッダに書かれてる enum 型は自動では変換されない?
それを(半自動で)やるのが#enum
例えば、
#include <stdio.h>
#enum CInt,, SEEK_CUR, SEEK_END, SEEK_SET
とすれば、seekCur, seekEnd, seekSetの三つが定義される
0458デフォルトの名無しさん
2010/12/19(日) 11:22:40ありがと、試したらできた。
あと、次のようにやると非常に分りにくいエラーが出ることも分った。
#{enum CInt,
, AAA
, BBB
}
でも、この形であっても = を付けて値を明示すれば問題なく変換される。
こういう物だとして受け止めておくが、この仕様は訳分らん。
0459デフォルトの名無しさん
2010/12/24(金) 12:49:400460デフォルトの名無しさん
2010/12/24(金) 13:02:39できないやつは振りをするよね。
0461デフォルトの名無しさん
2010/12/24(金) 16:43:530462デフォルトの名無しさん
2010/12/24(金) 19:16:45魔法発動のプロセスが暗に Haskell プログラミングになっている
ファンタジーな物語を小説にしようかと思ってるんだが
0463デフォルトの名無しさん
2010/12/24(金) 20:46:36少女はマッチを一本すりました。
すると、なんと小さな炎の中にテーブルが現れたではありませんか。
「まぁ、なんておいしそうなご馳走!」
しかし、副作用はありませんでした。
少女はマッチを一本すりました。
すると、なんと小さな炎の中に優しそうな青年が現れたではありませんか。
「まぁ、なんておいしそうなイケメン!」
しかし、副作用はありませんでした、
少女はマッチを一本すりました。
すると、なんと小さな炎の中に大企業の人事担当が現れたではありませんか。
「まぁ、これでやっと就職口が!」
しかし、副作用はありませんでした。
イブの日の小さな贈り物でした。
0464デフォルトの名無しさん
2010/12/24(金) 21:13:370465462
2010/12/24(金) 21:20:19遅延評価も頼む
0466デフォルトの名無しさん
2010/12/24(金) 21:43:59天使は同情の面持ちで「評価のときが来たのだ」と答えました。
スクルージは今までの自分を悔い、天使を見上げて問いかけました。
「私はやりなおすことができないのだろうか…?」
天使は同情の面持ちで「値を書き換えるのはバグのもとだ」と答えました。
0467デフォルトの名無しさん
2010/12/24(金) 22:07:490468デフォルトの名無しさん
2010/12/24(金) 22:18:52Shift-JIS を扱いたいんですけど、やっぱり無理ですよね?
掲示板でAAとか表示したいです
0469デフォルトの名無しさん
2010/12/24(金) 22:37:41Windows なら Win32API を使えばいい
他 OS は知らん
0470デフォルトの名無しさん
2010/12/24(金) 22:48:020471デフォルトの名無しさん
2010/12/25(土) 00:26:49でも最近のバージョンのghcだとそのままじゃビルドできなかったと思う。
例外周りが変わったせいらしい?
詳しくは覚えてないけどソース弄ってビルド通した記憶はある
0472デフォルトの名無しさん
2010/12/25(土) 01:05:10tomcatもオモチャみたいだけど
apacheあたりと組み合せないとダメでしょうか
0473デフォルトの名無しさん
2010/12/25(土) 01:16:51最近 haskell.org のヘッドライン・ニュースにでてたSNAPが面白そう。
http://snapframework.com/
0474デフォルトの名無しさん
2010/12/25(土) 08:35:06ldが馬鹿にメモリ確保してフリーズ?する
Windows2000 SP4 CPU MMX Pentium 200MHz、 メモリ 96MBだから?
i586CPUでも動くんじゃないの?
0475デフォルトの名無しさん
2010/12/25(土) 08:43:130476デフォルトの名無しさん
2010/12/25(土) 11:57:26これはメモリが少ないせいかな
0477デフォルトの名無しさん
2010/12/25(土) 12:01:103万もしないネットブックの方が遥か上のスペックだぞ
0478デフォルトの名無しさん
2010/12/25(土) 12:11:27組み込みだと普通だと思うけど
Win2000を使ってるのはおかしいが
0479デフォルトの名無しさん
2010/12/25(土) 12:13:450480デフォルトの名無しさん
2010/12/25(土) 12:18:140481デフォルトの名無しさん
2010/12/25(土) 12:20:100482デフォルトの名無しさん
2010/12/25(土) 12:21:310483デフォルトの名無しさん
2010/12/25(土) 12:30:390484デフォルトの名無しさん
2010/12/25(土) 14:08:52今時、組み込みでも300MHzていどは回さないとw
# まぁ、目糞鼻糞だが300MHzでx86-200MHzの倍程度のスピードはでる
0485デフォルトの名無しさん
2010/12/25(土) 14:19:230486デフォルトの名無しさん
2010/12/25(土) 16:01:490487デフォルトの名無しさん
2010/12/25(土) 16:45:470488デフォルトの名無しさん
2010/12/25(土) 16:55:160489デフォルトの名無しさん
2010/12/25(土) 20:46:22C 言語のソースから、宣言されている構造体を抽出するパーサーを作りたいです。
"struct aaa {...} bbb" という形の構造体そのものを解釈するパーサーは作れました。
しかし、その C 言語のソースは構造体以外にも余計な文字列があるので、
それらを「解釈しないで」省き、構造体だけを抽出したいです。
そういう場合は、まず正規表現で構造体部分の文字列を取り出してから、
それらをパーサーで解釈するという方法はあまりに拙いでしょうか?
構造体を表す文字列に出会うまで全ての文字列を捨てる、
というパーサーがなかなか作れません。
ghc 6.12.3
parsec 3.1.0
0490デフォルトの名無しさん
2010/12/25(土) 21:16:32関数本体とかは省略できるけど
プリプロセッサとかどうすんのかね
まあどうでもいいやねw
0491デフォルトの名無しさん
2010/12/25(土) 21:18:12しないしない
確かにOSだけで既にスワップ起こってるけど
自動優先度変更アプリ使って調整すれば
音楽聴きながらgvimでプログラミングできるよ
MinGWでコンパイルもできる
LibreOfficeも超モタツキながらも何とか動く
ghc --make でパッケージのSetupからexeファイル生成する時特有の現象なのです
あるいは小規模のmakeしかしてないから知らないだけか
多分既にスワップ起こしてるのにさらに
50MB程スワップ膨らませてるからだと思う
CPU使用率は20%くらいがずっと続くのにレスポンスは100%並にモタつく
これって処理の殆どがハードディスクとのI/O待ちって事でしょ?
0492デフォルトの名無しさん
2010/12/25(土) 21:18:22C言語のソースコードから自動でドキュメントを生成するツールがあるから、そのツールのソースコードを覗いてみればいいと思う。
0493デフォルトの名無しさん
2010/12/25(土) 21:19:19構造体を抜き出して何に使うの?
0494デフォルトの名無しさん
2010/12/25(土) 21:24:48コンパイルのときにガーベッジコレクションが頻発してるっていうオチか…
GHCもGHCでコンパイルしてるって話だったし
0495デフォルトの名無しさん
2010/12/25(土) 21:26:57>>489じゃないけど、構造体だけ抽出してスタブ作ってゲッターとかセッターとかの関数を自動生成したことならある
0496489
2010/12/25(土) 22:17:13>>495 と同じ知れない。
FreeType2 の Haskell ラッパーを作ろうとしてて、
構造体をデータ型で表現して Storable クラスのインスタンスにしたい。
正確には、hsc ファイル(の一部)を書くのを自動化して、
それで出力したコードを hsc2hs に入力する。
最初はライブラリ ドキュメントや C のヘッダーファイルを見て手作業でやってたが、
その構造体が比較的大きくて、量もそれなりにある。
ほとんど決まり切った形に変換していくのにイラついてきたから自動化させようと思って。
FreeType に限れば typedef struct AAA BBB; と typedef struct AAA {...} BBB;、
これだけ解釈できれば十分で、あとは手作業で楽に hsc ファイルが書ける。
本当は正規表現も使って本来の目的は達成できたんだが、
あまりにその場限りな感じの方法で、もっと洗練した方法があるか質問したかった。
>>492
探して見てみる、ありがと。
0497デフォルトの名無しさん
2010/12/26(日) 08:40:37今みたら、haskell用は無い見たいだけど、作ると喜ばれると思う。
0498デフォルトの名無しさん
2010/12/26(日) 12:26:13それをするには、まず swig の仕組みから勉強しないといけないんだよなぁ
0499デフォルトの名無しさん
2010/12/26(日) 12:29:27ただ、ASTがShowのインスタンスじゃないから、パースした後どういうデータ構造になるかチェックするのが大変だったけど
0500デフォルトの名無しさん
2010/12/26(日) 12:38:08cのソースじゃなくてlexやyaccのソース
0501489
2010/12/26(日) 14:01:37いや、たがらね、#include とか 関数とかグローバル変数の宣言とか #define とか、
その辺りを解釈しないで無視するパーサーを作りたかったんですよ。
解釈するパーサーは以前 Parsec で作ったんですけど、
無視するパーサーというのはどうやって作るのかなと。
(頭が硬いのか、うまく作れない)
一応、無視する仕組みは Parsec 以外のものを使って実現はできました。
私に対するレスではなく一般論でしたらすいません。
0502デフォルトの名無しさん
2010/12/26(日) 14:07:38struct に遭遇するまでは全てのトークンを空白と同じとみなせばいいだけだと思うんだけど、そんなにめんどい話かな
0503デフォルトの名無しさん
2010/12/26(日) 14:53:36こんな感じ↓で構造体作るときはマクロを多用するもんだと思ってたよ
#include <stdio.h>
#define coodinate( suf, type ) typedef struct { type x; type y; } coodinate##suf
coodinate ( S, short );
coodinate ( I, int );
coodinate ( L, long );
coodinate ( F, float );
coodinate ( D, double );
int main(void)
{
coodinateI p = {1, 2};
coodinateD q = {0.0, 1.0};
printf("x=%d, y=%d\n", p.x, p.y);
printf("x=%f, y=%f\n", q.x, q.y);
return 0;
}
0504489
2010/12/26(日) 15:03:11それは
T := <改行空白含めて struct 以外の任意の文字列> "struct" <struct 本体>
という構文規則を表現するパーサーなのでしょうか。
それとも、"struct" 以外の "#define" や "void" などのキーワードもとりあえず認識し、
認識した結果として、空白と同じように何もしないというパーサーなのでしょうか。
0505デフォルトの名無しさん
2010/12/26(日) 15:10:21どの程度詳しいパースをやるかはお前が決めることだろ
Cに完全準拠したパースをやりたいなら、完全なCパーサ(language-cでも自作でも)を使って
コード全体を解析した上でstruct以外を捨てるしかない
とりあえず動けばいいというならregexでも何でも使えばいい
その中間も当然あり得る
0506489
2010/12/26(日) 15:33:58> コード全体を解析した上でstruct以外を捨てるしかない
「解析しない」というのを Parsec で表現可能なのか、
それとも解析した上で捨てるしか Parsec では方法がないのか、
どちらかを聞きたかったんです。
言葉足らずで苛つかせてしまって申し訳ありませんでした。
> コード全体を解析した上でstruct以外を捨てるしかない
わかりました。
0507デフォルトの名無しさん
2010/12/26(日) 15:42:45単純なところを言えば、 struct が現れたところから解釈を始めるだけだと、コメント中や文字列中にあるものにもマッチしてしまう。
厳密にしようとすれば当然、完全な C パーサが必要。
0508デフォルトの名無しさん
2010/12/26(日) 15:46:100509デフォルトの名無しさん
2010/12/26(日) 15:49:04Parsecで // 〜行末 と /* 〜 */ を以外を抽出すればいいだけじゃ…
0510デフォルトの名無しさん
2010/12/26(日) 15:53:16「単純なところ」と書いたのはわかりやすいから。
もちろん、簡単に解決できるところではあるけど、
例外ケースを全部洗い出すと C パーサになるよ。
0511デフォルトの名無しさん
2010/12/26(日) 16:00:44ここをこめんととして使うなんてことはざらですよ
#endif
0512デフォルトの名無しさん
2010/12/26(日) 16:12:03それ、gcc -E で消えない?
0513デフォルトの名無しさん
2010/12/28(火) 00:59:54Haskellレベルで(IOでない)状態を扱うようなコードを書くときは積極的にStateモナドを
使うべきでしょうか。それとも引数をループで回すだけでよいでしょうか?
Stateモナドの使い方がパッと見ただけでは良く分からなかったので...。
0514デフォルトの名無しさん
2010/12/28(火) 01:06:22状況による。
0515デフォルトの名無しさん
2010/12/28(火) 01:42:17分かる方でやるべき。
後から修正が頻発するようなプログラミングをしてる場合にStateを使うべき。
ぱっと見でStateモナドが分かるならStateモナドを使えばいい。
0516513
2010/12/28(火) 02:16:22やはり使い分けですね。ありがとうございます。
>>515
> 後から修正が頻発するようなプログラミングをしてる場合にStateを使うべき。
おお、なんかリファクタリングっぽい。参考になります。
0517デフォルトの名無しさん
2010/12/28(火) 23:15:480518デフォルトの名無しさん
2010/12/29(水) 01:19:480519デフォルトの名無しさん
2010/12/29(水) 01:40:400520デフォルトの名無しさん
2010/12/29(水) 01:58:110521デフォルトの名無しさん
2010/12/29(水) 02:03:120522デフォルトの名無しさん
2010/12/29(水) 04:47:220523デフォルトの名無しさん
2010/12/29(水) 10:43:13そういうことだ
0524デフォルトの名無しさん
2010/12/29(水) 11:17:590525Perl忍者 ◆M5ZWRnXOj6
2010/12/29(水) 11:39:42さっさとスレ閉じて死んじまえよ
イワブキちゃん???
0526Perl忍者 ◆M5ZWRnXOj6
2010/12/29(水) 11:40:50壁にガンガンたたきつられたら haskellやめそう(笑)
0527デフォルトの名無しさん
2010/12/29(水) 11:42:17hack
0528デフォルトの名無しさん
2010/12/29(水) 22:25:29funca x y = x * y
funcb a b = a * b
main = print (funca == funcb)
これやってみたらどうなるんだろうと思いつつ試してみたら普通に
No instance for (Eq (a -> a -> a))
って怒られてしまったんですが、
もしEqのインスタンスであるとしたら一応同じということが言えるんですよね?
0529デフォルトの名無しさん
2010/12/29(水) 22:35:250530デフォルトの名無しさん
2010/12/29(水) 22:38:17どうもです
そこらへんはあんまり深く追わないことにします。
0531デフォルトの名無しさん
2010/12/29(水) 22:40:24同じという事が言えるように Eq のインスタンスを作れば、True となる。
0532デフォルトの名無しさん
2010/12/29(水) 22:47:08同じとは何であるかという話をしようよ
考えない方がいい、なんてよく言えたな
0533デフォルトの名無しさん
2010/12/29(水) 22:48:15例えばEqで「同じとは何か」を定義するときに
・ラムダ式の計算結果が同じになるか
と
・式の変数名まで同じであるか
のどちらを見るか次第では、TrueになるかFalseになるか変わる、という話になるんですかね
0534デフォルトの名無しさん
2010/12/29(水) 22:50:460535デフォルトの名無しさん
2010/12/29(水) 23:50:090536デフォルトの名無しさん
2010/12/30(木) 01:30:04いちおう、次の定義は動く。
{-# OPTIONS_GHC -XFlexibleInstances #-}
module Main where
import Data.Int
instance (Enum a, Bounded a, Eq a) => Eq (a -> a -> a) where
f == g = all (\(x, y) -> f x y == g x y) [(x, y) | x <- l, y <- l]
where l = [minBound..maxBound]
f1, f2, f3 :: Int8 -> Int8 -> Int8
f1 x y = x * y
f2 x y = x * y
f3 x y = x + y
main = do
print $ f1 == f2
print $ f1 == f3
print $ f2 == f3
でも、この Eq の定義が優れたものかどうかは、オレは知らない。
0537デフォルトの名無しさん
2010/12/31(金) 17:18:46前に釣りリンクここに書いてクリックした人数をカウントしたらたった23人だったよ
0538デフォルトの名無しさん
2010/12/31(金) 17:26:430539デフォルトの名無しさん
2010/12/31(金) 17:27:13それがソフトウェアの利点
0540デフォルトの名無しさん
2010/12/31(金) 17:27:340541デフォルトの名無しさん
2010/12/31(金) 17:27:580542デフォルトの名無しさん
2010/12/31(金) 17:32:440543デフォルトの名無しさん
2010/12/31(金) 17:35:310544デフォルトの名無しさん
2010/12/31(金) 17:44:460545デフォルトの名無しさん
2010/12/31(金) 17:57:550546デフォルトの名無しさん
2010/12/31(金) 18:00:08一応、新レスある度に見てます
0547デフォルトの名無しさん
2010/12/31(金) 19:13:40まあ再帰定義なわけだが
0548デフォルトの名無しさん
2010/12/31(金) 22:17:410549デフォルトの名無しさん
2010/12/31(金) 22:41:010550デフォルトの名無しさん
2010/12/31(金) 22:50:160551デフォルトの名無しさん
2011/01/01(土) 08:05:20できないのになんでそのコテ名乗ってんだよ
0552デフォルトの名無しさん
2011/01/02(日) 22:13:45で、小粒だがちゃんとしたアプリを作り上げてみたいんだが、
何かネタはないかね?
0553デフォルトの名無しさん
2011/01/02(日) 22:18:510554デフォルトの名無しさん
2011/01/02(日) 23:33:34ごめん
Windows の GUI アプリで何かネタ頼む
0555デフォルトの名無しさん
2011/01/02(日) 23:52:41じゃあぷよぷよクローン
0556デフォルトの名無しさん
2011/01/03(月) 00:16:10なるほど、ちょうどいいかも
ちょっと作ってみるわ
ありがと
0557デフォルトの名無しさん
2011/01/03(月) 11:24:290558Perl忍者 ◆M5ZWRnXOj6
2011/01/04(火) 00:16:370559デフォルトの名無しさん
2011/01/04(火) 00:19:570560デフォルトの名無しさん
2011/01/04(火) 00:32:07Functional Reactive Animation
それとも、FRP というのは以前から提唱されてて、
Haskell における FRP を意味論の点からしっかり形にしたのがこれなの?
0561デフォルトの名無しさん
2011/01/04(火) 11:43:110562デフォルトの名無しさん
2011/01/04(火) 12:21:14何の話だ?
0563デフォルトの名無しさん
2011/01/04(火) 13:11:220564Perl忍者 ◆M5ZWRnXOj6
2011/01/04(火) 17:48:160565デフォルトの名無しさん
2011/01/05(水) 17:09:24本家は reactive に継承されたからもう公開しないよって言ってる
0566Perl忍者 ◆M5ZWRnXOj6
2011/01/05(水) 21:23:410567デフォルトの名無しさん
2011/01/06(木) 11:53:470568デフォルトの名無しさん
2011/01/06(木) 12:43:10使ってるよ。
活用しているとは言えないけどね。
まだ、いろいろ実験して調べてるところ。
仕組みがいまいち分らん
0569Perl忍者 ◆M5ZWRnXOj6
2011/01/07(金) 20:05:510570デフォルトの名無しさん
2011/01/07(金) 21:31:34なかなかですね
0571デフォルトの名無しさん
2011/01/10(月) 11:31:18なぜGHCをインストールするには
MINGWをインストールする必要があるんですか?
0572デフォルトの名無しさん
2011/01/10(月) 12:06:41え? Haskell Platform を使えば、MinGWがどうとか考える必要はなくない?
C:\Program Files\Haskell Platform\2010.2.0.0\mingw 以下に入っているような、コンパイラとだかリンカだとかを使うんだろう。
少なくとも、GHCの開発者がGHC専用のDLL用リンカを開発しているとか考えにくい。
0573デフォルトの名無しさん
2011/01/10(月) 12:15:08STOPの意味がやっと分かった。
ではMINGWをインストールしてhaskell Platformの代わりにしよう。
0574デフォルトの名無しさん
2011/01/10(月) 13:05:42悪いことは言わん、初心者なら素直に Haskell Platform を入れとけ。
GHC 以外にも Cabal や hsc2hs などのツールもまとめてインストールされる。
入門書とか Real World Haskell とか解説サイトなどは、
そういうツールが既に入ってることが前提で説明されることが多い。
0575デフォルトの名無しさん
2011/01/10(月) 13:39:44MIDIファイルは作れるようになったんですが
こういうこと↓するには何をどうすればいいんでしょうか?
http://www.youtube.com/watch?v=eLS6GHXWMpA&feature=related
0576デフォルトの名無しさん
2011/01/10(月) 14:23:01よく分からないけど、それ、画面のキャプチャと音楽を動画編集ソフトでミックスしているだけなんじゃないの?
0577デフォルトの名無しさん
2011/01/10(月) 16:07:15Emacs のバッファ内に書かれた Haskell のソースコードをコンパイルして、
あるいはインタプリタで実行する Emacs Lisp を書けばいいだけだと思うが。
0578デフォルトの名無しさん
2011/01/10(月) 16:26:26レスありがとう
なんにせよ、GHCiには音を鳴らす機能はなくて、他のソフトなりが必要ってことですかね
0579デフォルトの名無しさん
2011/01/10(月) 16:36:25もしかして、haskore-realtime じゃないのか?
http://hackage.haskell.org/package/haskore-realtime
使ったことないから分らんが、
一時ファイルに midi を書き出すことなく、
リアルタイムに再生させるそうだ。
まぁ、音を鳴らすための外部ランタイムが必要そうだし、
まして UNIX 依存らしいが。
これを利用して、単に emacs 上でソースを保存したら則実行する
マイナーモードの lisp でも使ってるのかもね。
0580576
2011/01/10(月) 19:13:34これ、コーディング中(あるいはコーディング直後自動的に)そのコードを実行しているみたいね。
すでに言われていることだけど、flymakeみたいなEmacs LISPを使っているんだと思う。
おわびにちょっと調べてみる。
0581576
2011/01/11(火) 02:14:31重いし、もっとうまいやり方があると思うけど、いちようYouTubeのやつに似たことは出来るようになった。
下のやり方でためすなら、けっこう危険なEmacs LISPを使っているので、.emacs ファイルを事前にコピーしておいてください。
(1) まず、HaskoreはMIDIを演奏するとき、外部コマンドに丸投げの模様。
ttp://hackage.haskell.org/packages/archive/haskore/0.1.0.4/doc/html/src/Haskore-Interface-MIDI-Render.html
> playWin95 = play "mplayer" []
> playWinNT = play "mplay32" []
> playLinux = play "playmidi" ["-rf"]
> playAlsa = play "pmidi" ["-p 128:0"]
> playTimidity = play "timidity" ["-B8,9"]
> playTimidityJack = play "timidity" ["-Oj"]
外部コマンドに丸投げだから、timidityとかpmidiとかコマンドラインMIDIプレイヤーをインストールすれば、演奏できるようになる。
GHCiからでもO.K.
UbuntuだとTimidityパッケージかpmidiパッケージをインストールすればそのまま使える。
0582576
2011/01/11(火) 09:27:05(2) .emacs に次のように書き込む。
(defun auto-run-haskell ()
(let* ((app "auto-run-haskell")
(buf (current-buffer))
(_ (save-buffer buf))
(file (buffer-file-name buf))
(tmp (make-temp-file file))
(cmd1 (concat "ghc -o " tmp " --make -x hs " file
" > /dev/null 2>&1; echo -n $?"))
(cmd2 (concat "ghc -e Main.main -x hs " file))
(ret (shell-command-to-string cmd1))
(_ (when (file-exists-p tmp) (delete-file tmp))))
(when (equal "0" ret)
(when (get-process app) (delete-process app))
(start-process-shell-command app nil cmd2))))
;; つづく
0583576
2011/01/11(火) 09:29:58(let* ((mode mode-name)
(buf (current-buffer))
(file (buffer-file-name buf)))
(when (and (equal mode "Auto Run Haskell")
file
(string-match "\\.ahs\\'" file))
(auto-run-haskell))))
(define-derived-mode auto-run-haskell-mode
haskell-mode "Auto Run Haskell"
"An experimental major mode"
(add-hook 'after-change-functions 'auto-run-haskell-on-change))
(add-to-list 'auto-mode-alist '("\\.ahs\\'". auto-run-haskell-mode))
これで .ahs という拡張子で .hs のように編集すれば、編集ごとにコンパイルチェックをかけ、それが通れば実行される。
0585デフォルトの名無しさん
2011/01/11(火) 13:13:45・BehaviorとEventの相互変換ができるとあるんだけど(Flapjax)実装的にはBehaviorにChangedイベントのようなものがあってそれを受けて改めてイベントとして変わったことを発行するの?
・Behaviorってモナドなの?(モナドもよくわかってない)
・Behaviorは引数(時間など。なくても可)をもってPullして引っ張ってくる値、EventはPushされるものって理解だけどあってる?
C#やってF#で関数型学んだ奴なのでいろいろ間違ってそうなんだか聞けるのここぐらいだったので頼む・・・
0586デフォルトの名無しさん
2011/01/11(火) 19:37:39Flapjax は JavaScript ですよね。
Flapjax の実装はよく知らないので一つ目の質問には答えられないです。
> Behaviorってモナドなの?
実装に依ります。
例えば Haskell 用 FRP ライブラリ Reactivce では、モナドとしては実装されていません。
ただし、元になった論文には「意味的にはモナドだが、実際にはモナドとしては実装しなかった」
という言い方をしていますね(Event はモナドとして実装するのが便利とも言ってます)。
ただ、私自身は Behavior を陽に扱った FRP ライブラリを他に見たことがないので、
Behavior をモナドとして実装しているのは知らないですね。
> Behaviorは引数(時間など。なくても可)をもって・・・
これも実装に依ります。
というのも、そもそも Behavior や Event などは単なる概念なので、
その概念を表現・実現する方法は色々あります。
「概念的には」 Behavior は時間からある値への関数です(時間 -> 値)。
一方 Event は時間とある値のペアのリストです([(時間, 値)])。
Behavior をプッシュする実装もあれば、Event をプルするじっそうもあり得ます。
次の記事と論文がおすすめです。
・http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming
FRP って何? という質問と実装に関する創始者 Conal Elliott(ステキなじーさん)の返答。
67番のレス、今ならページの初めの方にあります。
・http://conal.net/papers/icfp97/
同氏と Paul Hudak 共著の論文「Functional Reactive Animation」
ちゃんと理論を提示した恐らく最初の FRP。
0587デフォルトの名無しさん
2011/01/11(火) 22:05:35>Haskell による FRP ではなく、FRP 全般の事を聞いてるのですか?
です。目的としてはF#でのFRPに近いものの実装なんですが。
そういう意味ではHaskellだとこんなにナイスに出来るよというのでも参考になります。
ざっくりとしてしか見てないんですが、FlapjaxではBehaviorはEventを継承したようなものでEventでかつ、その時の値(時間を引数とする値を返す関数である場合を含む)を持つもののようです。
ReactiveではBehaviorの値が変わったときに自動的に別のものに更新が伝搬したりするんでしょうか?するとしたらその仕組は?
FlapjaxではEventの延長であるので更新時になにか動作させるののイメージがつかみやすかったんですが。
おすすめのリンクの最初の方は読みました。が、なんつーか抽象的で掴みきれてないです・・・
自分的にはEventでのPushドリブンとBehaviorをPull的にしてそれにliftで汎用的にかければ実装も簡単だし効率的だし十分かなぁと。
が、他ではどんなにエレガントにやってるのかを漁ってるうちにドツボにw
FlapjaxのTutorialは割と具体的でつかみやすかったです。
http://www.flapjax-lang.org/tutorial/
例であがっているBehaviorである値をそのまま代入してどういうふうに実際の動作に結びついているのが不明なんですが。コンパイラによる?
0588デフォルトの名無しさん
2011/01/11(火) 22:33:52> ReactiveではBehaviorの値が変わったときに自動的に別のものに更新が伝搬したりするんでしょうか?
Reactive における Behavior は、プログラマにとってはまさに
Time -> a という型の関数に見えるように実装されています。
(引数として「時間」を受け取り、何か適当な型の「値」を返す関数)
時間 t を受け取ったらどんな値 v を返そうかというのをプログラマが定義するのですが、
Reactive の Behavior 型の値にはこれ以上の役割・機能はありません。
伝搬の意味が今ひとつ掴みかねてますが、
刻々と時間が経過してある behavior 型の値 v が変化しているとき、
ある関数 f を v に適用するようにプログラムを組んでいれば、
結局のところ関数 f は時間によって変化する値を返すようになりますね。
こうやって「時間による変化を伝える」ことは当然できますし、
プログラマが明示的にそのようにプログラムしないと伝わりません。
伝搬というのはこういう意味の事でよかったですか?
Flapjax の Tutorial は今ざっと読んでますので、
Reactive の behavior との違いがあるのか、などは後ほどレスします。
0589Perl忍者 ◆M5ZWRnXOj6
2011/01/11(火) 22:52:360590デフォルトの名無しさん
2011/01/11(火) 22:54:32今 Flapjax の Tutorial をざっと読みましたが、
Behavior と Event の概念は Reactive のそれと全く同じ、
つまり FRP 提唱者が最初に提唱したものと同じですね。
> FlapjaxではBehaviorはEventを継承したようなものでEventでかつ、その時の値(時間を引数とする値を返す関数である場合を含む)を持つもののようです。
私はそのような感じを受けなかったのですが、
チュートリアルのどの辺りからそのように感じたのでしょうか?
Flapjax においても、Behavior と Event は
一方が他方を包含したり継承したりするようなものではなく、
全く別のものではないでしょうか。
Behavior は連続時間上の振る舞いを表す、
方や Event は離散時間上の出来事を離散ストリームで表す。
もしかして、Flapjax ライブラリ自体の実装の話でしょうか?
0591デフォルトの名無しさん
2011/01/12(水) 00:03:15>伝搬の意味が今ひとつ掴みかねてますが、
イベントと同様に更新時にそれを参照しているものに何かの手段で伝わるかどうかという意味です。
アニメーションのように繰り返し評価されるため、更新されたことによる関連する値の再評価のタイミングなどを考えないものはいいと思いますが、表計算のようにグラフ的に更新が伝搬されるものが必要なモデルもあるのかと。
>Flapjax においても、Behavior と Event は
>一方が他方を包含したり継承したりするようなものではなく、
>全く別のものではないでしょうか。
Tutorialではないんですが、こちらのリンクの3.2の最後の方に
"Derived Behaviors A behavior in Flapjax is an extension
of event streams.
A behavior node maintains its current value, in addition to sources, sinks, and an update function"
などとあります。
まだ途中までしか読んでないんですが、このへん見てReactiveとは実装上は若干違うのかなと。
http://www.cs.brown.edu/~arjun/public/flapjax.pdf
0592デフォルトの名無しさん
2011/01/12(水) 07:53:35> アニメーションのように繰り返し評価されるため、更新されたことによる関連する値の再評価のタイミングなどを考えないものはいいと思いますが、表計算のようにグラフ的に更新が伝搬されるものが必要なモデルもあるのかと。
どうも伝搬の意味が分らない思ったら、私の方が遅延評価で考えていました。
Haskell は基本的に遅延評価なので、必要になるまで評価されません。
たとえば表計算でセルBがセルAを使って計算されているとします。
セルBの値が Event や Behavior を使ってセルAの変化に対応していたとしても、
セルBを再描画するなどの処理によってセルBの値が必要にならない限り、
セルBは自身が持つ Event や Behavior を評価しないのが基本です。
イメージとしては、Event や Behavior の発火元から情報が伝搬するのではなく、
セルなどの末端が必要に応じて発火元から情報を「引っ張ってくる」感じです。
芋づる式に。
なので、セルAが変化したタイミングで本来の情報(セルAの値)と一緒に
「セルBを更新してくれ」という情報も伝わらなければ Haskell では機能しません。
その仕組みをライブラリの中に埋め込んでいてプログラマには見せない方法もあります。
Reactive では逆にその仕組みを作るのをプログラマに任せています。
たとえば Event で「セルBを更新する関数」を伝えたり。
まぁそれでは発火元が情報を伝える先を知っていないといけないので、
普通は Reactive に更に1枚ラップを被せてその仕組みを作り、
末端のプログラマには内部のごたごたを隠して Haskell らしくしますね。
ちにみに、アニメーションは Reactive では一定時間間隔で発火する Event を作り、
その Event に「全画面更新をする関数」を乗せて実現するのが一般的です。
(つまり、一定時間間隔で連続時間の Behavior をサンプリングして離散化します)
0593デフォルトの名無しさん
2011/01/12(水) 09:41:43が、Eventではその更新された値自体は遅延で引っ張ってくるにしても、更新された事自体は正格的に実行はされるんですよね?
いずれにしてもReactiveでのBehaviorとEventの扱いがスッキリしました。ありがとうございました。
自分の実装でBehaviorをどんなふうに実装するかちょっと考えてみます。更新があった時点で副作用させたい時もあるだろうからなんかしらのEvent的なBehaviorは作るのかな・・・
ちなみに
>例であがっているBehaviorである値をそのまま代入してどういうふうに実際の動作に結びついているのが不明なんですが。コンパイラによる?
これはFlapjaxではコンパイラがliftしたものに展開してくれてるそうです。コレも楽そうでいいですね。
0594デフォルトの名無しさん
2011/01/12(水) 19:23:12> 更新された事自体は正格的に実行はされるんですよね?
そもそも、更新という概念じゃないんです。
更新という概念自体、命令型言語特有のものなので。
Reaqctive では結局のところ、adaptE という関数が提供されていて、
この関数を Event 型の値に適用すると、時間通りにイベントの内容を評価します。
たとえば e = [ (0.3, print "a"), (1.5, print "b"), ...] というEvent 型の値があったとします。
(正確にはこのように解釈できるモノです。実際はこんなふうに Event 型の値は作れません)
adaptE e とプログラムすれば、実行開始から 0.3 秒後に print "a" が初めて評価され、
1.5 秒後に print "b" が初めて評価され・・・、という感じです。
adaptE 関数の中身はライブラリに隠されていますが、
たぶん C 言語で言う while (true) {...} みたいな無限ループを作り、
現在時刻を計測しては Event を調べるというような泥臭いことをしていると思います。
(この辺りの実装テクニックの一部が先に紹介した論文で提案されています)
一方 Behavior の方は・・・
>>595 に続く
0595デフォルトの名無しさん
2011/01/12(水) 19:25:27一方 Behavior の方は、たとえば Behavior 型の関数 sinB があったとして、
print sinB なんてやっても意味が無く(そもそも型が合わないのでコンパイル不可)、
Event と組み合わせて使います。
具体的には、e = [(1, ()), (2, ()), (3, ()), ...] のような Event 型の値があったしとして、
e2 = sinB `snapshot_` e のようにプログラムすれば e2 の値は次のような値になります。
e2 = [(1, sinB 1), (2, sinB 2), (3, sinB 3), ...]
つまり 1 秒毎に sinB をその秒数で計算する関数を要素として持つ Event が作られます。
で、これを先ほどのように adaptE e2 とすれば 1 秒毎に Behavior が評価されるわけです。
もちろんアプリ的には計算だけでは無意味なので、print 関数など組み合わせて表示します。
なので、更新ではなく、どちらかというとサンプリングですね。
Behavior や Event の概念自体は全く同じでも、実装方法や、
ライブラリを利用するプログラマの考え方は Flapjax とは違いますね。
0596デフォルトの名無しさん
2011/01/12(水) 20:35:37イベントもなんですか。
むーなんかそこまでいくと色々と非効率になりそうな・・・
だからEventの実装が時間と値のタプルになってるんですか。
まぁ実装方法はいろいろだろうしそこはあまり問題ではないんですが。
F#などではFlapjax的に実装したほうがよさげっぽいです。色々と。
0597デフォルトの名無しさん
2011/01/12(水) 21:59:14> だからEventの実装が時間と値のタプルになってるんですか。
いや、だから「実装」は全然違いますって。
>>594 でも、正確にはこのように解釈できるモノと言いました。
FRP 提唱者が提唱した Event の概念が「時間と値のタプルの無限リスト」であり、
ライブラリ利用者も Event 型の値の意味をそのように解釈できるということ。
reactive の論文(http://conal.net/papers/push-pull-frp/)や、
ソースコードを読めば分りますが、実装は「効率的に実行できるように」
けっこう複雑な仕組みになってます。
余計なお世話だとは思いますが、実装より先に、
「実のところ FRP って何?」という部分をしっかり押さえた方が、
結局のところ近道だと思います。
で、私も説明が下手なので、やはり最初に提唱された時の論文を読んだ方が
断然いいと思います。
0598デフォルトの名無しさん
2011/01/12(水) 22:13:19言い忘れていました。
数ある FRP の中でも reactive はどちらかと言うと
アニメーションを得意としているような感じです。
と言うのも、作者(FRP 提唱者)が昔から
Functional Reactive Animation に興味を持ち続けているので。
だから、reactive のシステムを GUI システムの構築に利用するには、
その上に一皮ラッパーを被せたり、reactive を改造する必要があります。
reactive の前身である Fran もアニメーション用で、
Fran を GUI に利用した FranTk というライブラリが別の人によって作られましたが、
やはり Fran をそのまま利用する事はできず改造したと論文で述べています。
なので
> F#などではFlapjax的に実装したほうがよさげっぽいです
言語によってはというよりは、活用目的によって実装を考えるべきですね。
0599デフォルトの名無しさん
2011/01/13(木) 00:41:11すいません、自分は「概念」と「実装」の区別を場所によって明確に区別せず"実装"という言葉を使ってました。
>余計なお世話だとは思いますが、実装より先に、
>「実のところ FRP って何?」という部分をしっかり押さえた方が、
>結局のところ近道だと思います。
ここをしっかり押さえるのが正直難しいです・・・
ここ数日、いろいろ見て、で結局具体的にどういう事ができるの?というのを行ったり来たり。
ひとまずつくろうとしてるものに十分な感じにはつかめた気もしますが、もっと掘り下げると色々とエレガントにできそうな。
こちらもOCamlですがまた少し別の視点から実装してるようです。
http://ambassadortothecomputers.blogspot.com/2010/05/how-froc-works.html
>言語によってはというよりは、活用目的によって実装を考えるべきですね。
ですね。ひとまず必要な部分から手をつけていきます。
0600デフォルトの名無しさん
2011/01/14(金) 22:30:54によると、すでに(部分的に)GHCで書かれたアプリがApp Storeに並んでいるらしい
意外なところからHaskellが金になる可能性がでてきたな
0601デフォルトの名無しさん
2011/01/14(金) 23:02:080602デフォルトの名無しさん
2011/01/14(金) 23:24:060603デフォルトの名無しさん
2011/01/15(土) 00:35:200604デフォルトの名無しさん
2011/01/15(土) 08:28:57それとも専用のコンピューターがあれば関数型言語のまま実行できたりするんですか?
手続き型言語と関数型言語は同列に並んでるけど、本当は上下関係じゃないですか?
0605デフォルトの名無しさん
2011/01/15(土) 08:41:070606デフォルトの名無しさん
2011/01/15(土) 13:17:58機械語は関数型言語
0607デフォルトの名無しさん
2011/01/15(土) 23:18:36左再帰やFirst/First、First/Followのコンフリクトが起きますよね
よくRFCとかにABNFが載っているけど、これをそのまま書き下すと
左再帰はchainlがあるとしても
First/FirstやFirst/Followのコンフリクトが起きます
こういうコンフリクトは手動でBNFを変形して解決されてるのでしょうか?
もしそうだとすると、実用レベルではLRパーサのほうがいいのかなとか
思うのですが、いかがでしょうか
今作っているプログラムで、そこでちょっと詰まったもので
0608デフォルトの名無しさん
2011/01/16(日) 05:48:320609デフォルトの名無しさん
2011/01/16(日) 21:44:34parser = many1 letter `sepBy` delimiter
where delimiter = char ','
上はcharが区切りの場合ですが、
delimiter = string "hoge"ならmany1 letterの部分をどう書けばいいんでしょうか?
0610デフォルトの名無しさん
2011/01/16(日) 22:12:58何も変える必要ないよ
many1 letter のままでいい
なぜ何か変えないといけないと思った?
0611デフォルトの名無しさん
2011/01/16(日) 22:23:19many1 letter だとhogeにもマッチしてしまうためです
実際、結果もそのようになります
0612デフォルトの名無しさん
2011/01/16(日) 22:40:42あぁ、そういう事ね、確かに
以前やったような気がするから、ちょっと思い出してみる
0613デフォルトの名無しさん
2011/01/16(日) 23:11:46乱数以外のもっと簡単なStateの例題があったらおしえてください。
0614デフォルトの名無しさん
2011/01/16(日) 23:41:46逆に State を使わなかったとしたらと考えてみて。
状態を表す変数を受け渡さないといけないわけ。
その受け渡しを隠してくれるのが State モナド。
State に限らずモナドはそういった暗黙の受け渡しを担っていると言える。
もし今までにオブジェクト指向でのプログラミング経験があれば「カプセル化」が重要だということはよく知っていると思うけど、
モナドは Haskell においてカプセル化を実現するための機構と考えればいいと思う。
0615デフォルトの名無しさん
2011/01/16(日) 23:43:49圧縮展開で
スライド辞書をStateモナドで実装したことある
0616デフォルトの名無しさん
2011/01/16(日) 23:58:24・Stateのコンストラクタの引数が関数
・>>= の右側の引数が Stateを返す関数
この3点が難しくてひっかかる
0617デフォルトの名無しさん
2011/01/17(月) 00:26:03昔のソースコードを漁ってやっと思い出した
sepBy は使ってなかった
結局これで一応できる
many (try (manyTill letter $ string "hoge") <|> many1 letter)
かなり不格好になってしまった、もっと洗練された書き方があると思う
また、"hogeABChogeEF" の結果が ["", "ABC", "EF"] となって、
sepBy とは微妙に挙動が違うので注意
「文字列 s の直前まで任意の文字列にマッチするパーサー until」が作れれば、
until s `sepby` string s でできると思う
昔のソースコードには試みた形跡があるけど、面倒になって諦めたみたい
0618デフォルトの名無しさん
2011/01/17(月) 00:42:40コンティニュエーションの連鎖で次のものにいろいろ渡したり計算の前後でゴニョゴニョ処理を紛れ込ませられるって把握しとけば夜露死?
0619609
2011/01/17(月) 00:52:06manyTill letter (try $ string "hoge") <|> ..でいけました
結果はnot . nullでfilterして使うことにします
遅くまでありがとうございました
0620デフォルトの名無しさん
2011/01/17(月) 02:19:42(a,s) -> (a,s)
汚い
a -> s -> (a,s)
マジキチ
a -> State s a
0621デフォルトの名無しさん
2011/01/17(月) 08:14:23>>617
解決できればなんでも良いけど、それ、もしかして字句解析と構文解析を分けるべきところではないだろうか。
>>613
GHCのコンパイラ機能・インタプリタ機能をライブラリとして使うAPIが、独自モナドだけど機能的にはStateモナド(+ IOモナド?)と同じものを使っているよ。
さっき話題になっているParsecも、やはり機能的にはStateモナドの一種。Stateモナドとして実装することもできただろう。
0622デフォルトの名無しさん
2011/01/17(月) 10:53:490623デフォルトの名無しさん
2011/01/17(月) 11:12:25Emacs
0624デフォルトの名無しさん
2011/01/17(月) 12:53:13>>633 の他にも Editra や Yi も構文を解析して色を変えられる
構文を解析するほど機能的ではないが、
文の正規表現にマッチした所の色を変える程度でよければ、
(関数のシグネチャを定義する所とか、大文字で始まる識別子とか)
秀丸など他にもたくさんのエディタでできる
0626デフォルトの名無しさん
2011/01/17(月) 15:22:03履歴(↑、ctrl-p)の表示に時間が掛かることがたまにある
0627デフォルトの名無しさん
2011/01/17(月) 18:00:51うちは最新の Haskell Platform 入れてるけど、
ghci の履歴で待たされたと感じたことは一度もないな
履歴と言ってもせいぜい過去4、5件分さかのぼる程度だが
どのくらい時間掛かるの?
0628デフォルトの名無しさん
2011/01/17(月) 18:23:34数十秒
他の作業をしてghciに戻ってくるとよく発生する気がする
スワップアウトしてるのかな
0629デフォルトの名無しさん
2011/01/17(月) 19:24:55遅いのは履歴(↑、ctrl-p)の表示だけなの?
ロードとか、関数の評価とか、シェルコマンド実行とかはどうなのよ
そういうのは気にならんの?
再インストールした方がいいんじゃないかな
0630デフォルトの名無しさん
2011/01/17(月) 19:37:52遅いのは履歴だけだよ
それも一つ前の履歴を表示する時だけ
ていうか早漏すぎだろ
0631デフォルトの名無しさん
2011/01/17(月) 19:43:220632デフォルトの名無しさん
2011/01/17(月) 20:49:31haskeline で何か自作してみればいいんでないか
それでも数十秒も待たされるんなら、
そちらの PC と haskeline の相性が悪いんだろ
ちなみに、一度 ghci を :q で落としてから立ち上げ直すと、
しばらくは正常なのか?
それで実用上問題ないのなら、そういう使い方でも良いと思う
立ち上げ直しても、履歴は消えずに残ってるから
0633デフォルトの名無しさん
2011/01/17(月) 20:55:46サンクス
0634デフォルトの名無しさん
2011/01/18(火) 01:59:150635デフォルトの名無しさん
2011/01/18(火) 05:19:40だったら、後からコマンド一覧を見てコードの参考にしたいので、そのファイルの場所が知りたいです
0636デフォルトの名無しさん
2011/01/18(火) 19:02:38main=do cs <- getContents
threeline <- mapM return (take 3 $ lines cs)
mapM_ putStrLn threeline
自分の端末EOFがうまく入らなくて
設定するのもめんどくさくて
0637デフォルトの名無しさん
2011/01/18(火) 19:22:25let threeline = take 3 $ lines cs で良いと思う。
0638デフォルトの名無しさん
2011/01/18(火) 19:56:553行まとめて処理ではなくて
1行ごとに処理されて前より便利になって嬉しいんですが
これは何故なんでしょうか
0639デフォルトの名無しさん
2011/01/18(火) 20:01:33main = interact (unlines.id.(take 3).lines)
% main.ext < file.txt
0640デフォルトの名無しさん
2011/01/18(火) 21:01:57--run :: (CharParser () String) -> String -> String
myrepl f n = interact (unlines . (map f) . (take n) . lines)
main = myrepl (run p) 3
0641デフォルトの名無しさん
2011/01/18(火) 21:26:03getContentsは遅延IOだから所望する分だけ入力してくれるけど、mapMをかますことで一枚岩のIOとなるため。
遅延IOを操りたければ、System.IO.UnsafeのunsafeInterleaveIOを調べるべし
0642デフォルトの名無しさん
2011/01/19(水) 20:19:42myrepl f n = g >>= putStr . (unlines . (map f) . (take n) . lines)
where
g=unsafeInterleaveIO $ liftM2 (:) getChar g
main = myrepl id 3
0643デフォルトの名無しさん
2011/01/19(水) 20:49:16εを含む文法に対するパーサ(optionalやmany等)を<|>でつなぐ際、
εを含む文法のパースは必ず成功するため、
<|>でつながれている別のパーサにマッチしてくれません。
tryも機能しないのですが、どうやってバックトラックさせれば良いのでしょうか?
例えば(["+"] | "-") ...をパースする際、次のパーサだと
((option "" (string "+")) <|> string "-") >> string "1"
+1と1はパース出来ますが-1がパース出来ません
optionの前とstring "+"の前にtryを両方/片方だけはさむ3パターンも同様の結果です
LALR(1)のbisonではうまくいきました
同じくLL系のANTLRは構文木ごとにTreeWalkerなるものを
作らないといけないっぽくてきちんと確認するのはやめましたが
antlrworksでは-を通る図が描かれるので多分動きます
parser : ('+'? | '-') ('0' .. '9');
0644デフォルトの名無しさん
2011/01/19(水) 21:08:12根本的な解決になってるか知らんが、
<|> の右辺と左辺を逆にしたらいかんの?
(string "-" <|> (option "" (string "+"))) >> string "1"
つまり、εを含む文法を OR の一番最後で判定する
0645デフォルトの名無しさん
2011/01/19(水) 21:31:05わかる範囲では、基本的に指摘して頂いたような感じで解決しているのですが、
ただ、複数のεを含む非終端記号が<|>でつながれていたり、
修正がその非終端記号だけでは済まなさそうなものも多くて
手作業で修正するのは絶望的です(正しく動くか検証出来る気がしないです)
出来れば元のBNFは修正せずに何とかならないでしょうか
0646デフォルトの名無しさん
2011/01/19(水) 22:01:08他の構文解析器のことは知らんが、Parsec の run 系関数は、
入力されたパーサーが文法的にεを含んでいるかどうかを全く把握しない
(そもそも、各パーサーがεを含んでいる事を外部に知らせる術がない)
> 出来れば元のBNFは修正せずに何とかならないでしょうか
残念だが、現時点のバージョンの Parsec では何ともならんと思うぞ
> 手作業で修正するのは絶望的です
これは、Parsec で作った自分のパーサーを見て、
これは εを含んでいる、これは含んでいないと見分ける方法、
つまりアルゴリズムは持っているが、手作業では面倒だという意味か?
もしそのような意味であればラッキーだ
そのパーサーのプログラム文を解析し、
<|> の各項を適切な順に並べて出力するパーサーを作ればいい
その方法がない、あるいはそれも面倒なら、絶望的だな
0647デフォルトの名無しさん
2011/01/19(水) 22:31:53A = Be | Ce | De | F
Be = B*
Ce = C?
De = D >> string "" --この種もε?
これを書き換えるとすると
A = B' | C | D | e
B' = B+
最も外側にある<|>までさかのぼってこの種の変換をする
再帰関数を書くことでうまくいくかもしれないけど
正しく動くのか検証出来そうにないです
Maybe C -> C
みたいにパース結果の型も変わるだろうし
色々と調べてみて
RFCにあるようなBNFをそのまま記述するだけで何とかなる、
みたいな夢のパーサジェネレータはないのかなと思いました
そういうのを実現出来るものがあるとすれば
GLRみたいなアルゴリズムを実装するしかないんでしょうね
そうすると実用的な速度では動かないから
実用レベルでは、もうちょっと細かいハックが色々と要るってことなのかな
0648デフォルトの名無しさん
2011/01/19(水) 23:24:53Parsec や Haskell の勉強ではなく、純粋にある文を構文解析した結果を
Haskell で処理するのが目的なら、うまくいくという bison を
中間処理モジュールとして使えばいいのでは?
あるいは、LR 文法を解析する Haskell コードを生成する Happy を使うとか
これも yacc や bison などと同くコンパイラ コンパイラのひとつ
GHC で使われている実績もあって、コンビネータの組み合わせで表現する
Parsec などのパーサーより速いそうだ
ちらっと見たところ、ソースも yacc などとほとんど同じだ
(使ったこと無いから、あとは自分で調べてくれ)
0649デフォルトの名無しさん
2011/01/19(水) 23:35:38またレス番間違えた
>>648 は >>647 宛だ、すまん
今 Happy のユーザーガイドをざっと眺めてたら、
GLR パーサーが作れるみたいだな
(つまり、GLR アルゴリズムを使って構文解析する Haskell コードが生成される)
0650デフォルトの名無しさん
2011/01/20(木) 00:01:07GLRが解析出来るっていいですね
parsecを知るとbisonはちょっと使う気になれないので
happy調べてみます
マスコットがわりと癒し系
このぐらいの可愛さだと安心。>>439・・
0651デフォルトの名無しさん
2011/01/20(木) 00:47:10どうしてmanyTillの方だけtry必須なんですか?
0652デフォルトの名無しさん
2011/01/20(木) 01:43:20Data.IORef って、値の再代入をしてるんでしょうか?
それとも、内部では再代入をしないトリッキーな方法で、再代入の機能を実現しているのでしょうか?
0653デフォルトの名無しさん
2011/01/20(木) 07:52:22べつに必須というわけじゃない
必須なんてライブラリ ドキュメントのどこにも書いてないだろ?
次の2つのパーサーのパース結果を色んな文字列で比べてみればいい
manyTill (string "abc") (string "abd")
manyTill (string "abc") (try $ string "abd")
ちなみに、Parsec のソースの Combinator.hs を見てみれば、
この場合になんで try がいるのかすぐに分る
意外にシンプルに書かれたソースなんで、
ついでに他の関数の中身も見てみるといいよ
0654デフォルトの名無しさん
2011/01/20(木) 10:42:010655デフォルトの名無しさん
2011/01/20(木) 12:43:14具体的に聞け
0656デフォルトの名無しさん
2011/01/20(木) 14:38:140657デフォルトの名無しさん
2011/01/20(木) 18:08:30プログラムしやすいしデバッグもし易い。
なにより Haskell が使いやすい言語だし。
あくまで、Haskell に慣れ親しんだ者のごく主観的な「楽」です。
0659デフォルトの名無しさん
2011/01/20(木) 21:28:37> try抜きでは有用な使い道は無いと思うんですが
それは分るが、言いたかったのは
「manyTill だから必須なのではない」ということだよ
Aをパースして失敗したらBをパースする
という仕組みの「全ての」パーサーにおいて、
Aを途中までパースしかけたけど無かったことにしたい場合に、
try が必要になるだけのこと
manyTill がその仕組みになっていることは、
使い方やドキュメントから何となく分ると思うが、
ソースを見た方がよりはっきりするからソースの読解を奨めてる
関数の中で try を使っているかもしれないし、
プログラマに明示的に try を使ってもらうタイプのものかもしれない
そういう意味でも、やはりソースを見た方がいい
なぜ manyTill では try が要るのと考えていると、
他の提供パーサー、自作パーサーで同じような問題にぶつかり、
解決できなくてまた同じ質問することになりかねない
0660デフォルトの名無しさん
2011/01/21(金) 23:14:11C言語で作った同様のソフトは300KBでした。
0661デフォルトの名無しさん
2011/01/22(土) 02:14:34この辺は試した?
http://www.kotha.net/ghcguide_ja/latest/sooner-faster-quicker.html
どうしてもCよりは大きくなるとは思うけど。
0662デフォルトの名無しさん
2011/01/22(土) 02:18:04モジュールをオブジェクトファイルみたいに中身がテキストじゃないファイルに変換した後、モジュールのソースファイルを一切参照せずに、そのモジュールをimportしてコンパイルまでする方法ってないですかね
0663デフォルトの名無しさん
2011/01/22(土) 02:19:590664デフォルトの名無しさん
2011/01/22(土) 02:22:11.oファイルと.hiファイルを配布すればできるんじゃね?
オレはためしたことないけど。
0665デフォルトの名無しさん
2011/01/22(土) 02:36:10test.hs ... Module.hsをimportするファイル
% ghc -c Module.hs
Module.hs と Module.o ができるので、これを test.hs と同じディレクトリに置く(Module.hsは削除)
% ghc -o test test.hs Module.o -package p1 -package p2 -package p3
p1, p2, p3 は test.hs から import するGHCに附属する他のモジュール
でできた
0666デフォルトの名無しさん
2011/01/22(土) 02:39:100667デフォルトの名無しさん
2011/01/22(土) 06:11:41GHCのバージョンが配布元と一致してないと使えないのでかなり不親切
READMEに「ソースは読まないで下さい。読んだら呪う」とか書いとくのが良いと思う
0668デフォルトの名無しさん
2011/01/22(土) 10:50:57じゃ、静的リンクではどうだろう?
Wiinows環境で静的リンクってできたかよく知らんし、GPLやLGPLのライブラリと静的リンクして、オブジェクトだけ配布するのはライセンス違反だけどね。
0669デフォルトの名無しさん
2011/01/22(土) 11:27:02いったいどうすれば…
0670デフォルトの名無しさん
2011/01/26(水) 12:46:520671デフォルトの名無しさん
2011/01/26(水) 13:14:110672デフォルトの名無しさん
2011/01/26(水) 13:42:22Haskellだとそれができないから困る
0673デフォルトの名無しさん
2011/01/26(水) 13:44:400674デフォルトの名無しさん
2011/01/26(水) 15:14:580675デフォルトの名無しさん
2011/01/26(水) 15:37:26{ ; } でインデント依存をなくせばいいじゃない
0676デフォルトの名無しさん
2011/01/26(水) 15:49:55空白タブと{ ; }は単純に置換できないから、自動化は頭使うと思う
0677デフォルトの名無しさん
2011/01/26(水) 16:47:16空白や改行を増やしたり減らしたりしても、自動整形ソフトがあるから意味ないような。
0678デフォルトの名無しさん
2011/01/26(水) 18:02:13ソースは凄く見難くなるけど、Stream Fusion などの仕組みで
コンパイル後は結局普通のソースと同じ働きをするコードを吐くみたいな
0679デフォルトの名無しさん
2011/01/26(水) 18:19:26それ使えば難読化も可能じゃないかな
0680デフォルトの名無しさん
2011/01/26(水) 20:26:420681デフォルトの名無しさん
2011/01/26(水) 21:18:31ifM then else、caseM .. ofみたいな構文を入れてくれれば
caseの前に<-で一行増えるなんて悩みが無くなるのに
ifM :: (Monad m) => m Bool -> m a -> m a -> m a
だと今度は括弧がうざい
0682デフォルトの名無しさん
2011/01/26(水) 21:22:460683デフォルトの名無しさん
2011/01/26(水) 21:24:50ここで提案されてる\case構文が入れば、
condition >>= \case
True -> foo
False -> bar
みたいに書けるね
0684デフォルトの名無しさん
2011/01/26(水) 21:50:25https://github.com/darius/halp/
python2.xが要るけど、<M>-iでコメント行の式を評価してくれる。
--- 1+2
--- putStrLn "Hello"
とか書いといて<M>-iで評価すると
--- 1+2
-- | 3
--- putStrLn "Hello"
-- | hello
とかしてくれるし、ghciの機能である:tとか:iも打てる。エラーメッセージが出ないのだけが難点か。
0685デフォルトの名無しさん
2011/01/28(金) 10:59:110686デフォルトの名無しさん
2011/01/28(金) 22:15:01これをポイントフリー化しろっていう練習問題(wikipedia)に挑んだんですが
ttp://en.wikipedia.org/wiki/Tacit_programming#cite_note-1
多分こう変形出来ると思うんですが
f (g x y) ≡ (f .) (g x) y
一般にこれって言えるんでしょうか?
f (g a1 a2 ... an-1 an) ≡ (f .) (g a1 a2 ... an-1) a
(3つ連続してる点は関数合成ではなくa3 a4 と続いていくという意味)
0687デフォルトの名無しさん
2011/01/28(金) 22:42:380688デフォルトの名無しさん
2011/01/28(金) 23:22:05計算の組み立てをするという問題について、モナドは解のひとつだけど、最適解ではない
という話を聞いた
それが本当なら、モナド特化の構文はもうちょっと様子を見た方がいいと思う
0689デフォルトの名無しさん
2011/01/29(土) 00:35:110690デフォルトの名無しさん
2011/01/29(土) 01:34:010691デフォルトの名無しさん
2011/01/29(土) 02:37:06世界で一番か二番くらいにやさしい「モナド入門」
http://d.hatena.ne.jp/m-hiyama/20060419/1145432492
Arrowの紹介 for 2ch
http://www.aya.or.jp/~takuo/arrow_for_2ch/arrow_for_2ch.pdf
0692デフォルトの名無しさん
2011/01/29(土) 04:46:15Monadは、説明を聞くよりもStateモナドとListモナドを自分で再実装していじくりまわすのがお勧め。
0693デフォルトの名無しさん
2011/01/29(土) 05:34:400694デフォルトの名無しさん
2011/01/29(土) 08:35:460695デフォルトの名無しさん
2011/01/29(土) 12:59:41誰かがRxはモナドなのかとか言ってたがそれにはうまく答えられんがw
0696デフォルトの名無しさん
2011/01/29(土) 13:00:33アローの自分の理解
受け取り:関数
返すもの:(関数の引数の型)と(関数の戻り値の型)を入れた箱
アロー同士をくっつけて、関数を色んなやり方で合成出来る
関数A:文字列(テーブル名) -> 数値(主キー)を
関数B:数値(主キー) -> 文字列(名前)
関数C:数値(主キー) -> 性別(名前)
この3つに対応するアローを作って適切な順序で合成すると、
テーブル名を入力して、(文字列,性別)の組を返す関数が作れる
0697デフォルトの名無しさん
2011/01/29(土) 13:39:43わざわざアローを使う意義がわからんなぁ
それなら、普通に関数の合成でよくない?
アローによって抽象化された概念が、
関数の合成「以外」にも応用できないと、
抽象化の意味があまりないような気がする
アローによって抽象化された概念とやらが
一体何なのか未だによく分らんが
0698デフォルトの名無しさん
2011/01/29(土) 14:17:35そうかもしれない
0699デフォルトの名無しさん
2011/01/29(土) 17:47:37どうなってるのこれ
gtk2hsは0.10.1までで、cabal対応のgtk-0.11.2以降を使えってことなのかな
0700デフォルトの名無しさん
2011/01/29(土) 18:11:023分で解るHaskellのArrowの基本メモ
http://d.hatena.ne.jp/r-west/20070529
MonadとArrowの関係。
http://d.hatena.ne.jp/r-west/20070531
do記法でArrowを使いこなす基本メモ
http://d.hatena.ne.jp/r-west/20070604
ArrowによるHaskellプログラミングの基礎。…パイプ感覚で順次/分岐/繰返し
http://d.hatena.ne.jp/r-west/20070720
>>697
副作用がある特別な値を抽象化したのがモナドで、
副作用がある特別な関数を抽象化したのがアローですよね。
普通の関数合成はアロー合成の代わりにならないのでは?
0701デフォルトの名無しさん
2011/01/29(土) 18:44:16正確に言うと、MonadにはならないがArrowになる実例
パーサもFRPもXML処理もMonadになることが多そうだし
0702デフォルトの名無しさん
2011/01/29(土) 19:23:15> 副作用がある特別な関数を抽象化したのがアローですよね
そうなの?
「計算」という概念を抽象化して圏論の視点で構築したのがアローじゃないの?
モナドも「計算」という視点で捉え直せば Kleisli というアローで一般化できるのだと
アロー自体に副作用の概念は特にないと思ってたのだが
0703700
2011/01/29(土) 20:29:53正しくは「抽象化した」でなく「抽象化できる」ですね。
確かにアロー自体には副作用の概念はなく
副作用があろうがなかろうがアローにできます。
実際にアローを使うのは普通の関数では書けない時だから
その時はアロー合成を関数合成に置き換えられないという話です。
0704デフォルトの名無しさん
2011/01/29(土) 20:43:46確認なんだけど、結局同じ引数に適用したら同じ値に還元されるという意味において、
モナドは 100% アローで表現可能だし、アローは 100% モナドで表現可能だよな?
もしかして違うか?
違ってたら完全に私の認識が間違ってるっぽいから、
もう一度ちゃんと勉強し直したい
0705デフォルトの名無しさん
2011/01/30(日) 01:12:31> アローは 100% モナドで表現可能だよな?
違う。少なくとも、HaskellのControl.ArrowとContorol.Monadはそうではないし、
数学的にも、よく分からんが、たぶんデカルト圏かならずしもモナドならず、ということだと思う。
Arrowインスタンスにappメソッドが定義されていればそれはモナドと等価であるけど、定義されていない、定義できないのであればモナドではない。
appメソッドは次のように宣言されている:
class Arrow a => ArrowApply a whereSource
app :: a (a b c, b) c
Arrow記法で書くと
x <- aArrow -< aValue
と
x <- app -< (aArrow, aValue)
が同じ意味であるようなappを定義できるか、ということになる。
0706705
2011/01/30(日) 01:25:17data MyArrow a b = MyArrow {
runMyArrow :: a -> (b, MyArrow a b)
}
stepper :: b -> (b -> a -> b) -> MyArrow a b
stepper init f = MyArrow $ \a -> (f init a, stepper (f init a) f)
このMyArrow型はメモリのある電子回路のようなものをイメージしており、
例えば、
st = stepper 0 (+)
(x, st') = runMyArrow st 10
-- x = 10
(y, st'') = runMyArrow st' 5
-- y = 15
(z, st''') = runMyArrow st'' (-20)
-- z = -5
というように使う。
これをArrow、ArrowChoice、ArrowLoopのインスタンスにすることはできたのだが、ArrowApplyのインスタンスにすることは出来なかった。
考えみれば、
y <- stepper 0 (+) -< x
と
st <- arr (const $ stepper 0 (+)) -< ()
y <- app -< (st, x)
が同じ意味になるように定義することはできない。少なくともオレがモデル化しようとしていた回路の世界では。
上の例だと、その回路には最初からカウントアップする回路部品が含まれており、回路全体が繰り返し計算されることによってカウントアップされていく。
しかし、下の例だと、回路全体を計算するたびに新たにカウントアップ部品が生成されてしまうので、意味がない。
手前味噌かつ簡潔すぎて分かりにくいと思うが、まぁ、モナドに出来ない具体例は意外と簡単に見つかるよ、という話。
0707デフォルトの名無しさん
2011/01/30(日) 01:43:040708705
2011/01/30(日) 02:01:13> たぶんデカルト圏かならずしもモナドならず、ということだと思う。
というのは、分かっていないのにディレッタンティズムに駆られて余計なことを書いた。
これは取り消す。
0709デフォルトの名無しさん
2011/01/30(日) 02:24:53論文漁ってくる
0710デフォルトの名無しさん
2011/01/30(日) 08:05:22自分だけじゃないらしいので、少し安心した。
自分の中では「結合子(combinator)とMonad/Arrowとの違い」が分かっていない。
たとえば>>701は、Monadの例としてパーサ/FRP/XML処理を挙げているけど、少なくとも
・パーサ(形式言語の字句解析/構文解析)や
・XML処理(木構造をベースとした言語のvalidation/transfom/encode)は、
Monad/Arrowみたいな難しい概念を導入しなくてもcombinatorだけで書けるし、
その原理を説明できる。(FRPや副作用の話は知らない&分からない....)
実際Haskellでなくても、Monad登場以前の言語であるMiranda/Goferでもcombinatorで書けるし、
MLのようなinfix定義の可能な作用順評価(=非遅延評価)な関数型言語ならばcombinatorで書ける。
それどころかJavaやRubyのような非関数型言語でも表現力は劣るけどcombinatorで書ける。
(http://jparsec.codehaus.org/ を参照)
歴史を振り返れば、関数型言語への(ラムダ計算モデルにおける)combinatorという概念の導入は
BackusのFP(1978年)が最初の挑戦であり、その後にMLの型システム(1976-83年)によって
型安全性が保証され、さらにMiranda(1985年)によって正規順評価言語にも適用が拡大する。
そして最終的にこれら成果の結集としてHaskellが誕生し、Monad/Arrowへ発展していく。
自分の中では、おそらく>>702の言い方をマネすると
「combinatorを圏論の視点で再構築したのがMonad/Arrowである」
じゃないのかな?と想像してる。ただ、自分にはそもそもの圏論(category)が大きな壁に....。
というか、分かったつもりでいた初等代数系(群/環/体/束)に関する自分の知識(自信)が崩れ去り、
一から再勉強し直すことに...orz。やっぱりMonad/Arrowは難しいと思う。
0711デフォルトの名無しさん
2011/01/30(日) 08:37:32モナドは(a -> M b)が結合できるもので、アローは(A a b c)が結合できるもの、それにいろいろ理屈を付けただけでしょ。
モナドは結合する単位が(a -> M b)という関数の形に限定されるから、アローより限定的なものしか表現できない。
それでいいんじゃないの?
0712デフォルトの名無しさん
2011/01/30(日) 09:14:13その見方は大袈裟すぎ
パーサコンビネータのライブラリを良く見てみると、モナドとしての要件「も」満たしていることが分かった
→せっかくだからMonadのインスタンスにしようぜ
→do記法やらmapM_やらがタダで使えてハッピー
というだけ
別にコンビネータライブラリを書くときにMonadやArrowインスタンスを与えなきゃならんという決まりはないし、
実際Text.PrettyPrint.HughesPJなんかはモナドでもアローでもない
0713デフォルトの名無しさん
2011/01/30(日) 11:34:450714デフォルトの名無しさん
2011/01/30(日) 13:28:18勉強したみたいなら、Haskellのモナドを簡単に理解でるか
自分で試してみればいいんじゃね?
0715デフォルトの名無しさん
2011/01/30(日) 13:32:33それでいい人もいれば、それではなんか気持ち悪い人もいる、それぞれだ
俺は後者、理屈が分らんと気持ち悪い
理屈というか、「(a -> M b)が結合できるもの」とか
「(A a b c)が結合できるもの」を抽象化できないと気持ち悪い
抽象化できると(抽象化の過程が理解できると)、
たいていは今まで隠れてた本質が見えてくる
その抽象化の道具として今のところ数学が役に立ってるけど、
別のもので綺麗に抽象化できるならそれでもいい
0716デフォルトの名無しさん
2011/01/30(日) 13:45:39それでいいんだろうし、それはもっともな話だと理解できる。
ただ、
0717デフォルトの名無しさん
2011/01/30(日) 14:29:40「「(A a b c)が結合できるもの」を抽象化」、ってのがよくわからない
結合法則の利点がわからないとかそういう事なら
計算の順序を変えられる→計算を楽に出来ること、っていう例を知ればいい
例えば置換行列積の問題とか
0718デフォルトの名無しさん
2011/01/30(日) 14:31:010719デフォルトの名無しさん
2011/01/30(日) 14:41:22その辺の抽象化したらこんなナイスなことがあるよというのがわからんのよね・・・
使う分にはどこぞの説明であった副作用をすべて背後に押し付けて云々で良い気がするけれど。
0720デフォルトの名無しさん
2011/01/30(日) 14:51:10(A a b c) や 結合 に含まれた本質のみを抽出することを俺は抽象化と言っていて、
その抽出したものを表現するのに今のところおそらく圏論が役に立つであろうということ
(A a b c) って圏論的にはどういうこと?
結合、あるいは結合できるとは圏論的にはどういうこと?
というのを圏論の言葉で説明できると、圏論で培ってきた法則やテクニックが使える
そうして得られたものはまた Haskell の言葉で表現し直すことができそうだ
一見関係ない様々なものが群論というものに抽象化したことで理解が進んだように、
こちらは論圏で抽象化することで理解が進むのではないかと思われる
きみが「例えば置換行列積の問題とか」と言ったのも、
「(A a b c)が結合できるもの」を抽象化したものを行列の言葉で表現してる
自然に頭の中で普通に抽象化してるんだよ(特に意識してはいないと思うけど)
0721デフォルトの名無しさん
2011/01/30(日) 14:52:500722デフォルトの名無しさん
2011/01/30(日) 14:54:290723デフォルトの名無しさん
2011/01/30(日) 14:56:51ということかい?
0724デフォルトの名無しさん
2011/01/30(日) 15:01:13そういうことを期待している
ただ、まだ圏論自体を勉強してる最中だから、
本当に役に立つのかは俺自身は分らない
(役に立つことをまだ経験していない)
0725デフォルトの名無しさん
2011/01/30(日) 15:04:29「NoSQL=CoSQL」とか。
0726デフォルトの名無しさん
2011/01/30(日) 15:11:100727デフォルトの名無しさん
2011/01/30(日) 15:19:10(A b c)が順次結合できるだけなら、Control.Categoryクラス。
Control.Arrowクラスは、それに加えて、(b -> c)を(A b c)に変換できるarrメソッドと、平行化(?)できる***演算子などが定義されている。
(A b c)が順次結合できるっていうのは、圏論的にはもちろん射の合成に相当するだろう。
arrは、関数を射とする圏から(A b c)を射とする圏への関手に相当するだろう。
>>723,724
「これが圏論使ってこんな風に表現できるんなら、圏論のこの概念ってこういうのに応用できるんじゃね?」っていうのはオレには分からないけど、
MonadやArrowのdo記法の存在が既に圏論的な抽象化の産物であって、オレ様Monadやオレ様Arrowもその記法を利用することができるというのは、
小さくはない恩恵だと思う。
>>710のいうパーサ・コンビネータをモナドにする利点としても、数学的に云々という話ではないかも知れないけど、
Control.Monadのインスタンスにすればdo記法が使える、というのは大きな利点じゃないかな。
do記法なしでParsecを大規模に使うなんて、想像したくない苦行だと思う。
0728717
2011/01/30(日) 15:24:26自信ないが結合法則は圏論でも集合論でも意味は同じだと思う
圏論のMonad
T:(a -> b) -> m a -> m b
η:a -> m a
μ:m (m a) -> m a
Haskellのモナド(Kleisi triple)
T:(a -> b) -> m a -> m b
η:a -> m a
*:m a -> (a -> m b) -> m b
Arrow版は知らない
0729デフォルトの名無しさん
2011/01/30(日) 17:50:000730デフォルトの名無しさん
2011/01/30(日) 20:21:04Yampa
Grapefruit
などの FRP の実装とか
あとは ACM の Digital Library を漁ると色々出てくる
たとえば、Secure Information Flow にアローを利用する例とか
0731デフォルトの名無しさん
2011/01/30(日) 22:24:12こんな感じでHoogleに入れてみたんですが見つかりません
(Integer -> a -> b) -> [a] -> [b]
(a -> Integer -> b) -> [a] -> [b]
0732デフォルトの名無しさん
2011/01/30(日) 22:50:42f :: Int -> a -> b
g :: a -> Int -> b
zipWith f [0..] a
zipWith g a [0..]
0733デフォルトの名無しさん
2011/01/30(日) 23:35:520734デフォルトの名無しさん
2011/01/31(月) 01:47:20圏を形式体系の表現として使いたい(個々の射の形が重要)のと
関手を定義する際の枠組みとして使いたい(幾何的対象を如何に代数化するかが重要)のと
焦点が違うんじゃないかな.
0735デフォルトの名無しさん
2011/01/31(月) 02:51:23モナド則を自動チェックしてくれるわけじゃないし
モナド則破ってても見た目は普通に動いちゃうし
0736デフォルトの名無しさん
2011/01/31(月) 03:27:121月ってなってるのにもう1月終わるぞ
0737デフォルトの名無しさん
2011/01/31(月) 23:43:520738737
2011/01/31(月) 23:45:080739デフォルトの名無しさん
2011/02/01(火) 00:06:34標準ライブラリに存在するかという意味でしょうか?
であれば、残念ながらありません
また、実現する方法はクラス m に依るので、
任意のクラス m に対応する仕組みを作る、
ということもできないと思います
もしクラス m がモナドであれば、
タプルのそれぞれの要素に関数を適用し、
それぞれモナドを外してタプルにして
再びモナドで包むという、ごく普通の対応になると思います
f :: (Monad m) => (a -> m b) -> (a, a) -> m (b, b)
f g (x, y) = do
x' <- g x
y' <- g y
return (x', y')
0741デフォルトの名無しさん
2011/02/01(火) 00:24:30定番の方法というのは分からないけど、三つ思いついた。
import Control.Arrow
import Control.Monad
f, g, h :: Monad m => (a -> m b) -> (a, a) -> m (b, b)
f k (a, b) = liftM2 (,) (k a) (k b)
g k = runKleisli $ (Kleisli k) *** (Kleisli k)
h k = uncurry (liftM2 (,)) . (k *** k)
もし、課題が (a -> m b) -> (a, a) -> m (b, b)ではなく、(a -> m b) -> [a] -> m [b]であったなら、mapMがまさにそれ。
mapMのほうが一般性が高いし、とくにタプルにする理由がないのであれば、リストにしてmapMを使えば良いのではないかと思う。
0742デフォルトの名無しさん
2011/02/01(火) 00:30:31a -> m bはかなり特殊な型
ググってみたがforeverとか何に使うんだこれ
unsafeCoerce :: a -> b
forever :: Monad m => m a -> m b
mがリストなら
(a,a)->(m b,m b)ならぬ
[a] -> [[b],[b]]ときて
sequence :: Monad m => [m a] -> m [a]が使えそうな
0743デフォルトの名無しさん
2011/02/01(火) 00:52:23forever :: m a -> m b は、IOモナドなどを永遠に繰り返す関数。
引数の型 a は使用しないので何でも良い。
原理的に戻ってこないので、返り値の型 b は何でも良い。
というわけで、そういう方になっている。
unsafeCoerce は黒魔術にして変態技術。気にするな。
0744デフォルトの名無しさん
2011/02/01(火) 07:26:51forever は >>743 が言うように無限ループを引き起こす関数で、
FRP の活用でお世話になった
スレッドを分けて、他方を無限ループにして外部入力をポールする
unsafeCoerce はお世話になったことないな
0745デフォルトの名無しさん
2011/02/02(水) 13:01:56同じバージョンのパッケージをリビルドするだけでそれに依存するパッケージもリビルドしなきゃならない。
pkg.cabalでバージョン依存を-anyにしてもビルドするとその時のpkg-idに依存するようになっちゃう。
0746デフォルトの名無しさん
2011/02/02(水) 18:52:07パッケージを跨いで積極的な最適化をすることのトレードオフで、
インタフェースファイルの内容が実装に依存することになってしまう
0747デフォルトの名無しさん
2011/02/02(水) 19:05:54短いmainのいい記述法ってありますか
ghci、コンパイルエラーの時はimportしてる型の:tや:iが効かないため
とりあえずコンパイルだけしたいことが良くあるので
今のところ知ってる中では
main = return ()
これが一番短いです
0748デフォルトの名無しさん
2011/02/02(水) 19:43:46インポートだけ書いて ghci でリロードすればいいだけとちゃうか
そういう意味ではない?
0749デフォルトの名無しさん
2011/02/02(水) 19:45:470750デフォルトの名無しさん
2011/02/02(水) 20:01:40( ゜Д゜)なん・・だと・・?mainは要らなかったんですね
>>748
( ゜Д゜)なん・・だと・・?型注釈付けても動きよるです
0751デフォルトの名無しさん
2011/02/02(水) 20:03:260752デフォルトの名無しさん
2011/02/02(水) 20:10:58> 型注釈付けても動きよるです
そりゃそうだろ
動かなきゃ再帰なんてできない
0753デフォルトの名無しさん
2011/02/02(水) 21:13:470754デフォルトの名無しさん
2011/02/03(木) 09:37:55Next release: January 2011
Problems?
0755デフォルトの名無しさん
2011/02/05(土) 13:57:36という意味で正しい?
http://en.wikipedia.org/wiki/Join_and_meet
0756デフォルトの名無しさん
2011/02/06(日) 00:02:33よく分からないけど、どうしてそう思うのか教えてほしい。
0757デフォルトの名無しさん
2011/02/06(日) 01:15:47UML のクラス図のクラスとインスタンスの関係と同じように
両者を結んだ線のクラス側に三角形を描くようにするのでしょうか。
それとも、Haskell では一般的な図示の方法は提案されていないのでしょうか。
0758デフォルトの名無しさん
2011/02/06(日) 01:38:25あんまりまとまっていないからうまく説明できないけど、
前にスレに貼られていた論文
ttp://hdl.handle.net/10119/908
に、モナドというのは表示的意味論に関係が深いような記述があった。
表示的意味論というのは完備半順序という構造をとるデータ領域の意味を
領域上で連続な型コンストラクタの最小上界であるとする理論だと理解した。
補足的に完備半順序は別に完備束でもよいという記述を見つけたので、
束論を調べてみた。
ttp://ja.wikipedia.org/wiki/%E6%9D%9F%E8%AB%96
そこで、最小上界にあたるjoin(結び)という用語を見つけた。
これはなにかHaskellのControl.Monad.join(モノイドでは積にあたる)に
関係しそうだな、と思っていたところ、圏論の基礎のp189-190に
順序を保存するベキの構成に最小上界を取る操作を加えたものは完備半束になり
さらにそれは循環的な関手とみなせ、モナドになると書いてあった。
仮にjoinが最小上界を意味しないとすると、理論計算機科学の人たちは、
表示的意味論、束論、圏論、モナドを知りながら、Haskellにおいて、
混乱することが見込まれるのにjoinという用語を持ち出すことになる、
それは、少し考えにくいんじゃないか、と思ったから。
0759デフォルトの名無しさん
2011/02/06(日) 02:13:45ウェブ検索するのにたいへん都合が悪い。
もうちょっと変な語を定義して欲しいもんだ。
0760デフォルトの名無しさん
2011/02/06(日) 11:03:17> 理論計算機科学の人たちは、
> 表示的意味論、束論、圏論、モナドを知りながら、
関数を書く人全てが,意味論,圏論その他を統一された形で理解しているとは限らないし.
定義を見ると,Control.Monad.join は(圏論の)モナドの構造射のようだから,もっと適した
名前があると思う.「リスト関数の一般化」に分類されているから歴史的な理由で
join という名前がついているのだろう.
> HaskellのControl.Monad.join(モノイドでは積にあたる)
モノイドの積は二項演算だから例示としてあまり良くないのでは?
0761デフォルトの名無しさん
2011/02/06(日) 11:44:49数学詳しくないのでよく分からないけど、例えば次のような定義をした場合、
import Prelude hiding (return, fail, (>>=))
import qualified Prelude
import qualified Data.Set as S
class NewMonad m where {
(>>=) :: Ord b => m a -> (a -> m b) -> m b;
return :: a -> m a;
fail :: String -> m a }
instance NewMonad S.Set where {
m >>= k = S.unions $ map k $ S.toList m;
return = S.singleton;
fail _ = S.empty}
join :: (NewMonad m, Ord a) => m (m a) -> m a
join x = x >>= id
a, b, c :: S.Set Int
a = S.fromList [1,2,3,4,5]
b = S.fromList [2,4,6]
c = S.fromList [0,1,2,3]
d :: S.Set (S.Set Int)
d = S.fromList [a,b,c]
e :: S.Set Int
e = join d
-- つづく
0762デフォルトの名無しさん
2011/02/06(日) 11:48:36だから、この場合は概念的に関係があるけど、モナド一般に拡張できるかどうかはよく分からない。
0763デフォルトの名無しさん
2011/02/06(日) 12:16:15プログラムを書いた人がどうだったのかはわからないけれど、
Haskellにおいて華形だとみなされて当然な概念であるわけだから、
関与しているそれぞれの分野から注目されるという見込みは立つ。
開発指導層としては、華形のところにうっかり変な名前をつけちゃって
台無しになるなんて事態は避けるのが普通。必ずチェックを入れたはずだ。
でも、μにjoinという名前をつけたということは、何かしら他人を説得できる
理由というか名目があるんだろう。
二項演算ではないけど、型の二重入れ子を一重にしてくれて、図式を比較したら
対応しているところにあたるわけだから、対応しているといっても良くない?
積じゃなくて余積だといわれるのなら分かるけど。
0764デフォルトの名無しさん
2011/02/06(日) 12:21:52サンクス。読んでみる。
そういわれてみると、モナドで完備半束を表現できないとおかしい。
0765デフォルトの名無しさん
2011/02/06(日) 12:39:42だと意味がわかりにくくなるな
それでも、μにjoinという
で。
0766デフォルトの名無しさん
2011/02/06(日) 12:58:26トップダウンでライブラリや関数を作る場合はあなたの仰るとおりだと思う.
一方でローカルな関数/一時的な関数を一般化してライブラリに収めた,という場合
諸般の事情でオリジナルの名前が残ったとしてもおかしくない.いつか適切な名前に
改められるべきだとは思うけども.
経緯を知らない状況で「合理的な理由がある」と決め付けることは私にはできない.
>762
Control.Monad.join は要素の重複をそのまま残すので,いわゆる集合の join にはならないと思う.
0767デフォルトの名無しさん
2011/02/06(日) 13:01:43動かしてみたけど、確かに結び(join)になっているようだ。
意味論とトポロジーは関係あるそうだし、結び目の理論もモナドで実験できる
のかもしれん。全然知らないけど。
0768デフォルトの名無しさん
2011/02/06(日) 13:04:30前後した。重複を許すとはどういう風なもの。
0769デフォルトの名無しさん
2011/02/06(日) 13:34:26join [[1,1],[3,4]] は[1,1,3,4]
1は重複してるけど、これが問題になるってこと?
0770デフォルトの名無しさん
2011/02/06(日) 13:39:40join [[1,2,3],[2,3]] = [1,2,3,2,3]
{1,2,3} \/ {2,3} = {1,2,3}
ちなみに領域理論で使われるのは general topology で,結び目とかのいわゆる
「トポロジー」とは(多くの場合)大きく異なる.
あと,念のために書いておくと結び目は knot/link だからね.
0771デフォルトの名無しさん
2011/02/06(日) 13:40:02ここにいる人には必要ないかも知れないけど
ttp://snak.tdiary.net/20091020.html
0772デフォルトの名無しさん
2011/02/06(日) 13:53:22なるほど。なるほど。調べてみます。
0773デフォルトの名無しさん
2011/02/06(日) 18:55:500774デフォルトの名無しさん
2011/02/06(日) 20:28:05νはgreatest fixpoint
っていうのは再帰理論関係の方言みたいなものだから
Monadにおいてμでjoinを表わすのはjoinの定義が
μ. T T = T
になってることから来てるように思えるんだけど
何故greatestじゃなくてleastなのかってのがよくわからん
CPO(完備半順序)で μ (T(T(X)) < T(T(X))ってなってるってことなんだけど
直感ではネストが減ってるからとかそんな感じでgreatestはありえんという気はするけど
型付きラムダ計算の世界におけるCPOとしてはもう少し厳密な定義があるはずだよね
0775デフォルトの名無しさん
2011/02/06(日) 21:43:16理論的にはそういう感じで推測しました。
もし余モナドがあればjoinじゃなくてmeet(最大下界)になって、
最大不動点を意味するのかなと。
0776デフォルトの名無しさん
2011/02/06(日) 22:20:16圏論の基礎のp150に積はmeetで余積はjoinだ、という話が書いてあります
そこが関係するような。
でもそうすると、joinじゃなくてmeetにするべきのような気がしますね。
(余積の図式なので。)
0777デフォルトの名無しさん
2011/02/07(月) 15:56:05か教えてください。Linuxなどの場合は、
- Haskell Platformをインストールする
- それに含まれているcabalを使う
という手順のようですが、Haskell Platformのページに行くと、
Windows,Mac,Linuxのみの対応のようです。
0778デフォルトの名無しさん
2011/02/07(月) 16:08:08Solaris用のPlatformは用意されていないから
ソース( haskell-platform-2010.2.0.0.tar.gz )からビルドする。
ttp://hackage.haskell.org/trac/ghc/wiki/Building/Solaris
Solaris用のビルド手順はこちらにあるようです。
ttp://hackage.haskell.org/trac/ghc/wiki/Building/Solaris
0779デフォルトの名無しさん
2011/02/07(月) 16:34:08ソースのダウンロード先誤記失礼しました。
ttp://hackage.haskell.org/platform/linux.html
0780デフォルトの名無しさん
2011/02/07(月) 18:03:38どうしてるんやろ・・・・
0781デフォルトの名無しさん
2011/02/07(月) 20:19:44foldではマッチ後も余分な計算が発生するので
次のような関数を考えたのですが
既に用意されてる関数を組み合わせてこういうの出来ないでしょうか
(言い換えると、List.anyで最初にtrueになった要素に処理したい)
--空リストがあるので、結果は仕方なく1要素からなるリスト
dofirst :: (t -> Bool) -> (t -> a) -> [t] -> [a]
dofirst pred f lst = case lst of
[] -> []
x:xs -> if pred x then
[f x]
else
dofirst pred f xs
result=dofirst (==20) (*2) [1..]
0782デフォルトの名無しさん
2011/02/07(月) 20:33:38result = fmap (*2) $ find (==20) [1..]
0783デフォルトの名無しさん
2011/02/07(月) 20:42:55dofirst :: (t -> Bool) -> (t -> a) -> [t] -> [a]
dofirst p f = maybeToList . fmap f . find p
これが同じ関数になっているはず。
ただ、これが本当にやりたいことなのか疑問に感じる…
0784デフォルトの名無しさん
2011/02/07(月) 20:52:44バトルロワイヤルスレにいるPerl評論家ってのが奴じゃないのか?
0785デフォルトの名無しさん
2011/02/07(月) 20:56:34短い!エラー処理ではなくMaybeかー
やりたかったことは
dofirst p f = fmap f . find p
こうでした
0786デフォルトの名無しさん
2011/02/07(月) 21:24:15そんなにキッチリした経緯で決まっていると思わない方がいい。
理論の部分はともかく、用語は人間的な感覚の影響を受けるし。
0787デフォルトの名無しさん
2011/02/07(月) 21:38:34もう今更だから諦めてるよね、みんな
0788デフォルトの名無しさん
2011/02/07(月) 22:35:170789デフォルトの名無しさん
2011/02/07(月) 22:39:41説着曹操 曹操就到
0790デフォルトの名無しさん
2011/02/07(月) 22:42:13return という名称がダメだというのはみんなも認めるだろ
0791デフォルトの名無しさん
2011/02/07(月) 22:49:51理由としてはどういったものがあるの。
自分は結構マッチしていると思っているのでダメだというのがわからない。
0792デフォルトの名無しさん
2011/02/07(月) 23:05:50let f = return "test1" >> putStrLn "test2" >> return "test3" >> putStrLn "test4"
fの戻り値は "test1" でも "test3" でもない
0793デフォルトの名無しさん
2011/02/07(月) 23:07:25逆に何にマッチしてるのか訊きたい
0794デフォルトの名無しさん
2011/02/07(月) 23:09:300795デフォルトの名無しさん
2011/02/07(月) 23:09:590796デフォルトの名無しさん
2011/02/07(月) 23:12:34入門者にそう勘違いさせてしまうのが return の最大の問題だ
0797デフォルトの名無しさん
2011/02/07(月) 23:14:41>>=をコマンドラインのパイプのように理解しているから。
return aでaをパイプで処理できる形に変換
>>= f で処理可能にしたaに対してfを適用、で考えている。
0798デフォルトの名無しさん
2011/02/07(月) 23:36:28もしやC/C++とは無縁のお方?
0799デフォルトの名無しさん
2011/02/07(月) 23:43:28計算を返すという意味でC/C++のreturnとも合致していると思うが。
0800デフォルトの名無しさん
2011/02/07(月) 23:54:15> 1 |cat
というのはできない
> echo 1 |cat
としなくてはいけない。
入出力をたとえとして出しちゃっているので多分変な誤解が出るけど、
言いたいことは、ここでいうechoにあたるのがreturnだという意図なのだと思う。
echo :: 何か値 -> 入出力
だけど
return :: 何か値 -> モナド(というかコンピュテーション)
と一般化したものだと理解している。正しいかどうかは知らない。
だけど、そんな感じの論理でreturnと決まったんじゃないのかなぁと。
0801デフォルトの名無しさん
2011/02/07(月) 23:59:06WrapMonadとか意味わからなすぎる。
あと、Functorクラスの(.)とidは別のクラスにしておけとか、ArrowクラスのarrがArrowChoiceと対称性を損なっていてキモイとか。
0802デフォルトの名無しさん
2011/02/08(火) 00:07:55foldlだと駄目だと思うけど、foldrだといけるんじゃ?
dofirst p f = foldr k Nothing
where k a b = if p a then Just (f a) else b
-- dofirst (==20) (*2) [1..] => Just 40
dofirst' p f = foldl k Nothing
where k b a = if p a then Just (f a) else b
-- dofirst' (==20) (*2) [1..] => _|_
0803デフォルトの名無しさん
2011/02/08(火) 00:18:330804デフォルトの名無しさん
2011/02/08(火) 00:26:55理論的に美しいとか別にどうでもいいよ。
実用的に便利な組み合わせがあるのならそっちを優先するべきだし。
そもそも満足に綺麗に出来る保証なんてない。
自分は一般的に使えそうなところを探しているだけだよ。
0805デフォルトの名無しさん
2011/02/08(火) 00:40:49机上と実践じゃ必ずギャップ出るんだから。最初から現実的な落とし所で
考えておいたほうがリスクが少ないよ。
0806デフォルトの名無しさん
2011/02/08(火) 00:57:30かわいそうだね
言語オタとか死ねばいいよこういうやつら
何もつくれねえじゃん
なに作ってるのかな?
エジソン気取ってんの?笑
0807デフォルトの名無しさん
2011/02/08(火) 01:00:30そりゃ、理論的な美しさと実用性を比べれば実用性のほうが勝るかもしれないけど、MonadがApplicativeのサブクラスでないことは、実用性も損なっていると思うな。
ライブラリ製作者が注意すればよいこと、Contorl.なんちゃらカコイーな変態(オレとか)がいちいちinstance宣言かけばよいことではあるが、それでも僅かにであっても実用性を損なっている。
>>806
変態で悪いか? あぁ、悪いのか? オレが変態でお前に迷惑かけたか?
ああ、オレは変態だよ。それが何か問題か?
0808デフォルトの名無しさん
2011/02/08(火) 01:01:370809デフォルトの名無しさん
2011/02/08(火) 11:21:53芋(IMO):
- OCamlはネイティブバイナリ作るときにコンパイル時に使用するライブラリライセンスはLGPL (商用アプリ作るときに色々と面倒)
- 今後ゲーム開発は関数型言語が主流になるかもしれない話や研究活動は数年前からある。Haskellはその候補のひとつと考えている。
- 探すと意外と使われているし、開発も盛んである。あと俺のところで立ち上げる予定のサービスにC/C++, Perl, Ruby, PythonではなくHaskell使う予定だから(変態Haskell初心者で何が悪いか!)
- HaskellでOSを書いている人はたしか実在する。Houseだっけな。つまりGHCを使用してシステム記述にも使おうと思えば使える。
要するに頭の悪い否定癖を捨てて物事を両面から見ろってことだ。
0810デフォルトの名無しさん
2011/02/08(火) 12:03:450811デフォルトの名無しさん
2011/02/08(火) 12:45:00return が行う事、return が担っている役割が変なのではなく、
そういうものに return という名前が付いていることに違和感を感じている(と思う)
0812デフォルトの名無しさん
2011/02/08(火) 14:19:46(.)とidは、Categoryクラスでした///
0813デフォルトの名無しさん
2011/02/08(火) 15:16:50(.)とidを別のクラスにするのはどうして?
射の結合(.)とその単位元(id)は切っても切れない関係のような気がするけど。
0814デフォルトの名無しさん
2011/02/08(火) 17:10:13とっつきにくさは情報の整備によりある程度は解決するので
時間とコミュニティの方針の問題かな。
あと必要なら何故か存在しないGHCのユーザーズガイドの完訳を半年程度で
やるけど成果と最新安定版とのバージョン同期は期待しないでね(他も一人でやると半年では終わらない)。
0815デフォルトの名無しさん
2011/02/08(火) 18:20:10遅延評価!foldでは無理だと思っていました。なるほど、不思議
再度挑戦して
dofirst2 pred f x = find pred x >>= return .f
を経て
dofirst3 pred f = liftM f . find pred
→liftMとfmapって似てるなと思っているところです
0816デフォルトの名無しさん
2011/02/08(火) 19:54:41> 射の結合(.)とその単位元(id)は切っても切れない関係のような気がするけど。
圏としてとらえるならば(それはCategoryクラスの名前にかなったこと)、たしかに(.)とidが必要。
でも、圏としてとらえる以前に連結? 合成? できる有向グラフとしてとらえることもできるはずで、その場合は(.)はいるだろうけど、idはいらないんじゃないかな。
議論のために考えた例だけど、例えば
data Foo = Foo ...
data Bar a b = Bar {
runBar :: a -> (b, Foo)
}
のような型があった場合、Barに(.)を定義するのは簡単だが、直感的に自然な形でidが定義できるとは限らないでしょう?
>>815
ここ↓によれば
http://snak.tdiary.net/20091020.html
fmap = liftM は、FunctorでもMonadでもある型では必須の要件らしい。
0817デフォルトの名無しさん
2011/02/08(火) 21:34:07Applicativeはほとんど知らなかったのだけれどこれ?
ttp://www.soi.city.ac.uk/~ross/papers/Applicative.pdf
解説のほう読んだ限りだとなんというか、関手じゃないなにかマッピングするもので
写した射を関手のように取り扱いできるようにする、というのが基本アイディア
のようだね。
言いにくいし、よく知らないけど、これ実用面からの要請のみだと思うぞ。
(.)とidの話は正直よくわからん、どういうこと?
Arrowは全く知らないのでわからない。
liftMは循環的性質を持つ関手の射関数と考えればいいと思う。
0818デフォルトの名無しさん
2011/02/08(火) 21:53:51じゃおかしい
関手を適用したように取り扱いできる
で。
0819デフォルトの名無しさん
2011/02/08(火) 22:07:13サイト情報ありがとうございます。
>>728の型みたいにFunctorはMonadを含んでいる(機能的にはFunctor⊂Monadだけど)ので
常にMonadはFunctorのインスタンス、ってことなのかな
ただ、実装でそれを強制されてはいない(と思う)ので
より特殊化されているliftMを使ってる方が安心な気がします
ところでポイントフリーを調べていて、W(\x y -> x y y)コンビネータに行き着いたのですが
前に話題になったjoinの型 μ:m (m a) -> m aは、Wの型(a -> a -> b) -> a -> bと対応してるそうですね
(m aは1引数関数と見なせるので(a -> m -> m) -> (a -> m)と見ると型は近い)
ttp://stackoverflow.com/questions/4333864/trick-for-reusing-arguments-in-haskell
>>728の型も眺めてみるとη:a -> m aはK(あるいはKI)コンビネータと対応してるように見えなくもないし
T(fmapやliftM)もなんかのコンビネータと対応してるのかも
0820デフォルトの名無しさん
2011/02/08(火) 22:26:34ごめん。オレには>>816以上にうまく説明できないし、オレが何か勘違いしている可能性もある。
0821デフォルトの名無しさん
2011/02/08(火) 22:56:42一応これ読めば対応はわかるとおもう。
ttp://www.ipsj.or.jp/07editj/promenade/4703.pdf
モナドの構成要素に関手が入っているので、理論としてはモナドと関手は切り離せない。
fmapとliftMはつかう文脈によりけりでいいんじゃないか。
他の領域に写すだったらfmapで上の階層(コンピュテーションの世界)に
上がるだったらliftMとか。
>>820
普通のidと関手F上のid_Fとで区別する必要があるとかならあるのかもしれないけど
よくわかんない。
0822デフォルトの名無しさん
2011/02/08(火) 22:57:44その圏論からモナドまで説明してある本ってないですかね?
本屋にいったけど、圏論の本なかったです
0823デフォルトの名無しさん
2011/02/08(火) 23:05:04さっきも書いたけど対応としてはこれ
ttp://www.ipsj.or.jp/07editj/promenade/4703.pdf
あと日本語系だと以下など
ttp://ci.nii.ac.jp/naid/110003743465
ttp://ci.nii.ac.jp/naid/110003743466
ttp://ci.nii.ac.jp/naid/110003743564/
さがすと結構あるし、自分も探し中。
0824デフォルトの名無しさん
2011/02/08(火) 23:12:37個人的にはつくりながらわかるこれがオススメ。
ttp://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.2885
Schemeだけど。
0825デフォルトの名無しさん
2011/02/09(水) 00:24:45いまさら英語が読めないなんて言えないっ
0826デフォルトの名無しさん
2011/02/09(水) 02:01:42えっと、ごめん。http://www.kotha.net/ghcguide_ja/latest/ とは別のもの?
0827デフォルトの名無しさん
2011/02/09(水) 12:07:39これは失礼。あったのですか。
他に訳されていないもの探してみます。
0828デフォルトの名無しさん
2011/02/10(木) 00:44:47バチェラーだけじゃ無理
0829デフォルトの名無しさん
2011/02/10(木) 00:50:42ライブラリ製作に役立ったよ、って経験者はいる?
0830デフォルトの名無しさん
2011/02/10(木) 01:10:36さっぱり分からん
0831デフォルトの名無しさん
2011/02/10(木) 07:52:22邦題を決めた奴は地獄の業火の中に投げこまれるべきである
0832デフォルトの名無しさん
2011/02/10(木) 17:41:19Arrow が Categoryのサブクラスなので (.)とidを Categoryクラスで定義するのはしょうがないと思うが。
> ArrowクラスのarrがArrowChoiceと対称性を損なっていて
これはどういう意味?
0833デフォルトの名無しさん
2011/02/10(木) 23:03:22自分の言葉で言わないとわからなくなるだけだよ。
Arrowは全く知らない。機能を難しくしても、個別の機能にまつわる話が
分散化していくだけで、あんまり意味というか仕事にならないと思う。
0834801
2011/02/10(木) 23:51:50Arrow から arr を除き、それと ArrowChoice のデフォルト宣言に手を加えると、それぞれのクラスはだいたい次のようになる
class Arrow a where
first :: a b c -> a (b, d) (c, d)
first x = x *** id
second :: a b c -> a (d, b) (d, c)
second x = id *** x
(***) :: a b c -> a b' c' -> a (b, b') (c, c')
(&&&) :: a b c -> a b c' -> a b (c, c')
class ArrowChoice a where
left :: a b c -> a (Either b d) (Either c d)
left x = x +++ id
right :: a b c -> a (Either d b) (Either d c)
right x = id +++ x
(+++) :: a b c -> a b' c' -> a (Either b b') (Either c c')
(|||) :: a b d -> a c d -> a (Either b c) d
Arrowの宣言の first を left に、 second を right に、*** を +++ に、 &&& を ||| に、(a,b) を Either a b に、a b c を a c b に置き換えれば、ArrowChoiceの宣言と全く同じ。
(a,b)が集合の直積、Either a b が集合の直和に相当することを考えても、この対称性(あるいは双対性?)は明白だと思う。
0835デフォルトの名無しさん
2011/02/11(金) 01:20:480836デフォルトの名無しさん
2011/02/11(金) 01:31:290837デフォルトの名無しさん
2011/02/11(金) 14:53:33途中まで読んでだいぶ挫けそう、というか飽きかけてる
圏論を知っていたから Haskell でこういうプログラムができるようになった、
Haskell のこういう事が理解できるようになったとかいう自慢話は何かない?
圏論を学ぶ道の先に Haskell の輝きが見えるとモチベーションが維持できるのだが
0838デフォルトの名無しさん
2011/02/11(金) 17:53:08>>変態で悪いか? あぁ、悪いのか? オレが変態でお前に迷惑かけたか?
>>ああ、オレは変態だよ。それが何か問題か?
>>807
変態気取り うわ〜お前みたいなやつ人のまね
変態的コード とかいうやつの真似
yusukebeのまね
お前は真似野郎猿真似帰れよ猿
チンパンだね キモ
0839デフォルトの名無しさん
2011/02/11(金) 18:16:5610章まで行って、やっとモナド則が必要な理由が分かる程度
0840デフォルトの名無しさん
2011/02/11(金) 22:01:08うん、君の役には立たないし義務教育ってわけでもないから
話がわからないなら教室から出ていっていいのに
座り込んで泣くわ喚くわ小便を漏らすわ
もうね
0841デフォルトの名無しさん
2011/02/11(金) 22:21:35圏論の Haskell への応用って話は私だけでなく、
他の人も知りたがっている事だと思ってたが、違うのか?
きみは知りたくないのか?
0842デフォルトの名無しさん
2011/02/11(金) 23:37:28ただ、それでも、以前も書いたことだけど、オレは MonadやArrowのdo記法の存在が、圏論による抽象化の小さくない恩恵だと思っている。
他には、例えば、\x -> fmap f1 $ fmap f2 $ fmap f3 $ x = fmap (f1 . f2 . f3) ということにすぐに気が付き、関数を短く書けるということも、圏論による抽象化の恩恵なんだろう、たぶん。
あと、次のような例を思いついた。モノイドを圏に変換しているんだけど、これは(すぐに挫折した)『圏論の基礎』からの知識を使っている。
import Prelude hiding ((.), id)
import Control.Category
import Data.Monoid
data Monoid m => MonoidCategory m a b = MonoidCategory m
mc :: Monoid m => m -> MonoidCategory m () ()
mc = MonoidCategory
runMC :: Monoid m => MonoidCategory m () () -> m
runMC (MonoidCategory a) = a
instance Monoid m => Category (MonoidCategory m) where
{ id = MonoidCategory mempty
; (MonoidCategory a) . (MonoidCategory b) = MonoidCategory $ a `mappend` b }
foobar = runMC $ (mc "Foo") . id . (mc "Bar")
-- foobar => "FooBar"
0843デフォルトの名無しさん
2011/02/12(土) 00:10:58分からないなら分からないと素直に言った方がいいと思う
0844デフォルトの名無しさん
2011/02/12(土) 00:20:43モノイドは圏なのに、圏に変換する理由が分からないです
あと、「圏論の基礎」は日本語がおかしい
0845デフォルトの名無しさん
2011/02/12(土) 00:29:40ワケわかんねぇもんあれ。
英語でもAwodeyの本とかの方がよっぽど分かりやすい。
日本語なら分量が少ないけど
http://www.amazon.co.jp/dp/4320026578
の圏論の章が比較的わかりやすいと思う。
絶版なんで図書館かどっかで借りるしかないけど。
0846デフォルトの名無しさん
2011/02/12(土) 08:53:16学校でHaskellを選択して今>>4の・Haskell: The Craft of Functional Programming を読んでいます。
それで少し分からないのが
square ::Int ->Int
square n= n*n
です。
すみませんが中々分からないので教えていただけませんか?おねがいします。
0847デフォルトの名無しさん
2011/02/12(土) 09:45:420848デフォルトの名無しさん
2011/02/12(土) 11:41:54ソースコードとコンパイルしたプログラムが1対1じゃないのが気に食わない。
http://cdsmith.wordpress.com/2011/01/16/haskells-own-dll-hell/
この記事の3. Can we stop cabal-install from breaking the package database?
の項目でcabalが依存関係を壊す典型的な例を出してるけど、例えば二つのhaskellプログラム、
yiとかgititとかの、たくさんの依存パッケージを持つ応用プログラムを同時に入れようとすると確実に壊れる。
・cabalが無闇にパッケージのリビルドをしない
・ghcが同じソースコードのビルドで違うid,hashを作らない
どっちかで解決できるはずなんだけどなあ。
0849デフォルトの名無しさん
2011/02/12(土) 12:40:430850デフォルトの名無しさん
2011/02/12(土) 14:56:47ちょっと気になった
まぁ、ホントどっちでもいいことだが
0851デフォルトの名無しさん
2011/02/12(土) 15:22:20あなたが何が分からないのか、こっちには分からない・・・
一行目の「square :: Int -> Int」は型宣言。
「関数 square は、32bit符号付整数型を受け取って、32bit符号付整数型を返す関数ですよ」と、関数 square の『型』を宣言している。
(Intが何bitかは、厳密には環境依存だったはずだけど、たいていは32bit)
二行目の「square n = n * n」は関数宣言。
「関数 square は、ある値(n)を受け取って、それを n * n と計算して返す関数ですよ」と、関数 square の『実装』を宣言している。
「*」は四則演算の乗法(掛け算)だから、n * n は n の二乗を計算している。
もしかして、「型」というものが分かっていない?
>>848
よく分からないんだけど、
> ?Package foo depends on bar-0.5 and baz-1.2.
> ?Package flox depends on bar-0.5 and baz-1.1.
> ?Package bar-0.5 depends on baz, but has no preference between versions 1.1 and 1.2.
fooは、bar経由で間接的にbaz(に含まれるモジュール)をインポートしており、それとは別に自分で直接bazをインポートしており、自分がインポートしているbaz-1.2と整合させるために、baz-1.2に依存するbar-0.5が必要。
floxも同様に、自分がインポートしているbaz-1.1と整合させるために、baz-1.1に依存するbar-0.5が必要。
でも、bar-0.5は一つしかないので両方の要件を満たすことはできない、という問題だと理解してよい?
0852デフォルトの名無しさん
2011/02/12(土) 15:54:25うん。>>848の記事にもあるけど、.cabalファイルのバージョン指定がパッケージによって厳しすぎる/緩すぎるのも一因。
で、殆どのパッケージ、応用ソフトがそんな依存関係を持ってる。
ttp://www.mail-archive.com/[email protected]/msg72276.html
このCabal dependency hellのスレッドも似たような問題の話をしてる。
hackageに上げたパッケージは、バージョンを変えずに.cabalファイルの記述を変えることができないのが問題だとか、
いやそういう修正をするならfoo-0.5をfoo-0.5.1と微修正してくれるよう開発者にお願いすればいいとか、色々言われてる。
個人的にはパッケージャーが全バージョンの動作検証をするのは大変だから、利用者の報告、検証をもっと簡単にできた方がいいと思う。
他には、自分の使ってるディストリだと内部のソースの変更ではない、パッケージ情報の変更だけとかの場合、
バージョン番号の他にあるリリース番号を上げて対応するとかしてる。依存関係の記述にリリース番号を含むことはできなくしてる。
0853Perl評論家
2011/02/12(土) 15:56:59見るだけで頭が痛くなる
0854デフォルトの名無しさん
2011/02/12(土) 16:14:44技が引き継がれてると鬱陶しいな
0855デフォルトの名無しさん
2011/02/12(土) 16:17:27error :: [Char] -> a
error s = throw (ErrorCall s)
undefined :: a
undefined = error "Prelude.undefined"
throw :: Exception e => e -> a
throw e = raise# (toException e)
というわけで、raise# の意味論や実装に依存。
意味論としては、よく説明されるように_|_という特別な値がすべての型に含まれていて・・・ という理解でひとまず十分で、その視点では副作用は存在しないんだと思う。
raise# の実装は、たぶん普通のラムダ計算の枠組みに収まらないものになっているだろうけど、それを「副作用」と呼ぶのが適切かはよく分からない。
0856デフォルトの名無しさん
2011/02/12(土) 19:02:54>(Intが何bitかは、厳密には環境依存だったはずだけど、たいていは32bit)
64bit版のLinuxではIntは64bitみたい。
Cのintは32bitのままだから、ちょっと意外だ。
64bit版Windowsではどうなってるのかな。
0857デフォルトの名無しさん
2011/02/12(土) 22:57:48fix :: (a -> a) -> a -> a
fix f x = let y = f x
in if x == y then x else fix f y
この関数 fix に例えば次のような関数を適用させるとします。
f :: a -> a
f x = if {x を使った述語} then x else {x を変化させた値}
fix f {a 型の適当な値} とやったとき、
もし関数 f の {x を使った述語} が真なら x そのものを返していますが、
それでも関数 fix 内の x == y では a 型の同値関数 (==) が適用されます。
この場合、x と y は同じものを指しているにもかかわらずです。
この挙動は当然と言えば当然なんですが、値ではなく、指している対象同士で
同じかそうでないかを比較する仕組みは作れないものでしょうか。
というのも、実際のところ a 型に相当するのが画像データを格納した
けっこう大きな Array 型なんです。
Array 型のソースを見てみましたが、(==) 関数の定義は重そうですし、実際重いです。
指している対象同士で比較できれば処理速度が速くなるのですが。
0858デフォルトの名無しさん
2011/02/13(日) 00:05:44どこか別に話ができるところとかないもんですか。
0859デフォルトの名無しさん
2011/02/13(日) 00:09:30モナディックになってしまうが、MArray のインスタンスを使うのはどうだろう?
import Data.Array.IO
import Control.Monad
fix :: (Eq a, Monad m) => (a -> m a) -> a -> m a
fix f x = do
{ y <- f x
; if x == y then return x else fix f y
}
f' :: Monad m => (a -> m Bool) -> (a -> m a) -> a -> m a
f' p k x = do
{ b <- p x
; if b then return x else k x
}
f = f' (getBounds >=> return . (0==) . fst) (\a -> writeArray a 0 100 >> return a)
main = do
{ x <- newListArray (0, 10) [0..] :: IO (IOArray Int Int)
; y <- fix f x
; assoc <- getAssocs y
; print assoc
}
つづく
0860デフォルトの名無しさん
2011/02/13(日) 00:13:11http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.0.0/src/GHC-IOArray.html#IOArray によれば
newtype IOArray i e = IOArray (STArray RealWorld i e)
instance Eq (IOArray i e) where
IOArray x == IOArray y = x == y
で、http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.0.0/src/GHC-Arr.html#STArray によれば
-- Just pointer equality on mutable arrays:
instance Eq (STArray s i e) where
STArray _ _ _ arr1# == STArray _ _ _ arr2# =
sameMutableArray# arr1# arr2#
なので、 IOArray や STArray を使っているかぎり、(==)は要素の比較のみしてくれるはず。
モナディックにするのがいやなら、配列を生成/変更するときにハッシュ値でも計算してそれを比較するようにするとか。
0861デフォルトの名無しさん
2011/02/13(日) 12:56:25>>860
> なので、 IOArray や STArray を使っているかぎり、(==)は要素の比較のみしてくれるはず。
要素の比較ではなくて、参照で比較するから速いんですよね。
アドバイスを受けてから調べてみましたが、こんなページを見つけました。
http://www.macs.hw.ac.uk/~dsg/gph/docs/4.06/users_guide/ghc-language-features.html
ここにも、要素同士の比較ではないと書かれていました。
> モナディックにするのがいやなら、配列を生成/変更するときにハッシュ値でも計算してそれを比較するようにするとか。
なるほど、そういう方法もありますね。
今思いつきましたが、どこがどう変更されたのかは知る必要は無く、
直前のものから変更された事だけ分れば十分なので、生成変更するたびに
2値の On Off スイッチみたいなものもをいっしょに記録しておく手もありそうです。
前回が On で今回も On なら終了とか。
両方の方法で試してみます。
アドバイスありがとうございました。
0862デフォルトの名無しさん
2011/02/13(日) 18:43:37> 要素の比較ではなくて、参照で比較するから速いんですよね。
あれ? なんで、「要素の比較」なんて書いたんだろう。
おっしゃるとおり、「参照の比較」の誤りです。ごめん。
0863デフォルトの名無しさん
2011/02/15(火) 00:27:530864デフォルトの名無しさん
2011/02/15(火) 06:39:560865デフォルトの名無しさん
2011/02/15(火) 07:15:500866デフォルトの名無しさん
2011/02/15(火) 10:09:40ふたばみたいなBBSつくりたいんだけど、
今は、むりやり日本語を数字にコーディングしてデータベースに保存してる
AAがあるので、Shift_JISを扱いたいです
0867デフォルトの名無しさん
2011/02/15(火) 12:35:00ライブラリじゃいかんのか
0868デフォルトの名無しさん
2011/02/15(火) 13:28:01例の氏名公開事件は完全にAphaiaに問題があると思うけど、Yassieがあそこまで激しく嫌悪しているのは、それじゃないでしょ?
0869868
2011/02/15(火) 13:33:24ほんとうにごめんなさい。
0870デフォルトの名無しさん
2011/02/15(火) 13:53:49Haskellくだ質スレが無いから
0871デフォルトの名無しさん
2011/02/15(火) 23:05:51State型を返すreturnへの型注釈はどうやって付ければいいですか
statereturn :: a -> State ???
statereturn = return
最終的にやりたいことは
ttp://www.sampou.org/cgi-bin/haskell.cgi?Memoise
ここにあるmemoise/ins/findにState型を使って型注釈をつけることです
0872Perl忍者 ◆M5ZWRnXOj6
2011/02/16(水) 00:55:330873Perl忍者 ◆M5ZWRnXOj6
2011/02/16(水) 00:58:42デッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデ
r'ニ;v'ニ;、
デッテイウ _,!゚ ) i゚ ) .iヽ デッテイウ デッデデッデ
r=、r=、 / `ヽ,. ┘ ヽ デッデデッデ
デッテイウ ,、 ,、 .__{゚ _{゚ _} i ′′ }
, - (゚(゚ ))> /´l r `'、_,ノi、 l、 、 ,! デッデデッデデッデデッデデッデデッデ
r-=、( '' ,r'⌒゙i>_{ ) ヽ.____,ノ` 、 ! デッデデッデ
`゙ゝヽ、ヽー´ ,,ノ::``、 _.r(_ ノ゙`ー. ヽ,.┬/ | /7 デッデデッデデッデデッデ
にー `ヽ、_ /::::::::ィ"^゙リ-r _,,ノ ,. lー' /ニY二ヽ デッテイウ
,.、 `~iヽ、. `~`''"´ ゙t (,, ̄, frノ `ァ-‐ /( ゚ )( ゚ )ヽ
ゝヽ、__l::::ヽ`iー- '''"´゙i, ヽ ヽ,/ / /⌒`´⌒ \ デッデデッデ
W..,,」:::::::::,->ヽi''"´::::ノ-ゝ ヽ、_ノー‐テ-/ i | (-、 |
 ̄r==ミ__ィ'{-‐ニ二...,-ゝ、'″ /,/`ヽl , ヽ___ノ | ト- :、
lミ、 / f´ r''/'´ミ)ゝ^),ノ>''" ,:イ`ヽ | |r┬ー| l ,/;;;;;;;;;;;;`゙
! ヾ .il l l;;;ト、つノ,ノ / /:ト-"∧ l | / //;;;;;;;;;;;;;;;;;;;
. l ハ. l l;;;;i _,,.:イ / / ,レ''";;;;;ヾ二,-;;´;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
人 ヾニ゙i ヽ.l yt,;ヽ ゙v'′ ,:ィ" /;;;;;;;;;;;;;;r-'"´`i,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; デッデデッデ
r'"::::ゝ、_ノ ゙i_,/ l ヽ ゙':く´ _,,.〃_;;;;;;;;;;;;f´' ll;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
` ̄´ / l ヽ ヾ"/ `゙''ーハ. l;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
/ l ゙t `' /^t;\ ,,.ゝ;;;;;;;;;;;;;;;;;;;;;;;;;;;
0874デフォルトの名無しさん
2011/02/16(水) 01:02:33a -> State s a じゃない?
0875デフォルトの名無しさん
2011/02/16(水) 03:40:28かわいそうだねぇ・・・なんどみても
873 :Perl忍者 ◆M5ZWRnXOj6 :2011/02/16(水) 00:58:42
デッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデデッデ
r'ニ;v'ニ;、
デッテイウ _,!゚ ) i゚ ) .iヽ デッテイウ デッデデッデ
r=、r=、 / `ヽ,. ┘ ヽ デッデデッデ
デッテイウ ,、 ,、 .__{゚ _{゚ _} i ′′ }
, - (゚(゚ ))> /´l r `'、_,ノi、 l、 、 ,! デッデデッデデッデデッデデッデデッデ
r-=、( '' ,r'⌒゙i>_{ ) ヽ.____,ノ` 、 ! デッデデッデ
`゙ゝヽ、ヽー´ ,,ノ::``、 _.r(_ ノ゙`ー. ヽ,.┬/ | /7 デッデデッデデッデデッデ
にー `ヽ、_ /::::::::ィ"^゙リ-r _,,ノ ,. lー' /ニY二ヽ デッテイウ
,.、 `~iヽ、. `~`''"´ ゙t (,, ̄, frノ `ァ-‐ /( ゚ )( ゚ )ヽ
ゝヽ、__l::::ヽ`iー- '''"´゙i, ヽ ヽ,/ / /⌒`´⌒ \ デッデデッデ
W..,,」:::::::::,->ヽi''"´::::ノ-ゝ ヽ、_ノー‐テ-/ i | (-、 |
 ̄r==ミ__ィ'{-‐ニ二...,-ゝ、'″ /,/`ヽl , ヽ___ノ | ト- :、
lミ、 / f´ r''/'´ミ)ゝ^),ノ>''" ,:イ`ヽ | |r┬ー| l ,/;;;;;;;;;;;;`゙
! ヾ .il l l;;;ト、つノ,ノ / /:ト-"∧ l | / //;;;;;;;;;;;;;;;;;;;
. l ハ. l l;;;;i _,,.:イ / / ,レ''";;;;;ヾ二,-;;´;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
人 ヾニ゙i ヽ.l yt,;ヽ ゙v'′ ,:ィ" /;;;;;;;;;;;;;;r-'"´`i,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; デッデデッデ
r'"::::ゝ、_ノ ゙i_,/ l ヽ ゙':く´ _,,.〃_;;;;;;;;;;;;f´' ll;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
` ̄´ / l ヽ ヾ"/ `゙''ーハ. l;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
/ l ゙t `' /^t;\ ,,.ゝ;;;;;;;;;;;;;;;;;;;;;;;;;;;
0876デフォルトの名無しさん
2011/02/16(水) 09:25:100877デフォルトの名無しさん
2011/02/16(水) 14:47:010878デフォルトの名無しさん
2011/02/16(水) 15:33:490879デフォルトの名無しさん
2011/02/16(水) 16:43:50import Control.Monad.State
data Player = Player {hp :: Int} deriving Show
addHP :: Int -> State Player ()
addHP h = do
oldp <- get
put $ oldp {hp=(hp oldp)+h}
return ()
こんな感じのaddHPの途中でIO処理(例えばputStrLn "HPが加算されました")をするにはどうすればいいんですか?
できれば実際にコードを書いてください。
よろしくお願いします。
0880879
2011/02/16(水) 17:03:37addHP :: Int -> StateT Player IO ()
addHP h = do
oldp <- get
liftIO $ putStrLn $ "OldHP: " ++ (show$hp oldp)
put $ oldp {hp=(hp oldp)+h}
return ()
main = runStateT (addHP 7) (Player 8) >>= print
0881デフォルトの名無しさん
2011/02/16(水) 18:35:34>>879-880
普通のやり方がどうなのかわからないけど
動くものを練習で書いてみました
data Player = Player {hp :: Int} deriving Show
pgen hp = (put (Player hp))>>=(\_ -> return( putStrLn ("Player hp:"++(show hp))))
infixl 6 +>
(+>) st aug=
let dummy = Player 0 in
let player = execState st dummy in
let next =(evalState st dummy) >> putStrLn ("hp +"++show aug) in
let updated = player {hp= (hp player) + aug} in
State (\x -> (next,updated))
display x = let r = runState x (Player 0) in
fst r >> putStrLn (show $ snd r)
main = display $ pgen 10 +> 1 +> 1000 +> 100
0882デフォルトの名無しさん
2011/02/16(水) 19:57:54たぶん、理解しているんだろうけど、main の 最後の print がオレを不安にさせる。
"OldHP: ..." を表示させたいだけなら、それはいらないよ。
それと、addHP の 最後の return () もいらない。
そのほか、オレなら、こういう感じに書くかな。
addHP n = do
Player m <- get
liftIO $ putStrLn $ "OldHP: " ++ show m
put $ Player $ n + m
>>881
MTL のバージョン、古くない?
オレの環境(2.0.1.0)だと、Stateデータコンストラクタはエクスポートされていないみたいなんだけど。
で、pgen の >>= は >> に変えられる。
+> は オレならこう書く:
(+>) :: State Player (IO ()) -> Int -> State Player (IO ())
st +> n = state k
where
act = putStrLn $ "hp +" ++ show n
k s = let (act', Player i) = runState st s
in (act' >> act, Player $ i + n)
0883デフォルトの名無しさん
2011/02/16(水) 21:52:45演算子の定義の仕方と、dummyが要らない書き方がとても参考になりました
whereのほうが宣言的に見えますね
mtlのバージョンは1.1.0.2(HaskellPlatformの付属品)でした
道理でStateコンストラクタを使ってるコードをあまりみないわけか
Readerのコンストラクタが使えるのに気づいて
類推から使ったら動いたもので
0884Perl忍者 ◆M5ZWRnXOj6
2011/02/17(木) 09:20:51みんな、あさだよ
0885デフォルトの名無しさん
2011/02/17(木) 14:26:02いぇ〜い
0886デフォルトの名無しさん
2011/02/17(木) 14:29:53それとも頻繁な更新にはリストは不向きですか?
0887デフォルトの名無しさん
2011/02/17(木) 16:15:56take n xs ++ [x] ++ drop (n+1) xs
0888デフォルトの名無しさん
2011/02/17(木) 17:08:240889デフォルトの名無しさん
2011/02/17(木) 17:40:14頻繁に更新するなら Data.Map のほうが効率的。
0890デフォルトの名無しさん
2011/02/17(木) 17:46:44浜崎あゆみとかノネナールキツいよおじちゃん
0891デフォルトの名無しさん
2011/02/17(木) 17:50:120892デフォルトの名無しさん
2011/02/17(木) 17:52:23ハスケル詳しくない俺が答えるけど
ハスケルは参照透過性の為に基本、更新=新しく作り直し
だから遅いよ。膨大なデータを一カ所書き換えるが為に
別のメモリ空間に変更無しの所まで一からコピーし始める様を想像してみなよ
頻繁な更新には向かないね。
勿論策はある。それは他の人たちが答えてくれるよ
0893デフォルトの名無しさん
2011/02/17(木) 17:54:12あ、小室てつやに振られてメンへラになった女の方だっけ?
いずれにせよ加齢臭するわ
0894デフォルトの名無しさん
2011/02/17(木) 18:08:18> 膨大なデータを一カ所書き換えるが為に
> 別のメモリ空間に変更無しの所まで一からコピーし始める様を想像してみなよ
普通の実装だと、変更無しの所まで一からコピーされはしないよ
変更ヶ所の部分だけ、ポインタを指し替えるだけ
0895デフォルトの名無しさん
2011/02/17(木) 18:37:00あり^^
走査はあるの?
ここは前と同じだからパス
ここもパス
:
あ、ここは変更点ね。新規生成してポインタ差し替えます
ここはパス
ここもパス
:
はい終わり
膨大なリストになるとこれでも馬鹿にならないコストでは?
0896デフォルトの名無しさん
2011/02/17(木) 18:54:12こんな感じで、詳しく無いとか、わかる範囲とか
そういう答え方しか出てこないのが怖い
haskell刷れ
0897ぱるぱる
2011/02/17(木) 19:05:32みんな、ばん御飯の時間だよ
0898デフォルトの名無しさん
2011/02/17(木) 19:54:22君は >>892 で、ハスケルは参照透過性の為に更新=新しく作り直しだから遅いと言った
その事を理解する比喩として「メモリ空間に変更無しの所まで一からコピー」を挙げた
私はその比喩が妥当ではないと言っている
明らかに私の言い方が悪かったために正しく伝わらなかったのは認める
たとえば x = [a, b, c, d, e] というリストの3番目の要素である c を v に変えるとする
それをコンピュータで実現するための方法は様々あるが、(少なくとも)モダンな実装では、
メモリ内に [a, b, c, d, e] と [a, b, v, d, e] の両データを存在させるようにはなっていない
つまり、[a, b, c, d, e] と同じデータをもう一部コピーし、
その中の3番目の要素を v に変えるなんてことはしない
リスト は [a] -> [b] -> [c] -> [d] -> [e] -> Empty というポインタの数珠つなぎだから、
[b] -> のポイント先を [v] -> [d] -> [e] -> Empty に指し替えるだけだ
[a] も [b] も [d] も [e] も、メモリ内にはひとつしか存在しない
たしかにn番目の要素を変えるには、「普通は」1番目、2番目と辿っていく必要があるため、
君の >>895 の感覚は妥当だ(それが正しい「遅い理由」だ)
しかし、>>892 の比喩は、そのようなリスト操作が遅いことを理解する比喩としては全く的外れだ
0899デフォルトの名無しさん
2011/02/17(木) 20:39:33現実世界ともう一つ、訳のわからん世界の二層構造だったということだ。
0900デフォルトの名無しさん
2011/02/17(木) 20:40:35あり^^
0901デフォルトの名無しさん
2011/02/17(木) 20:50:54そんな実装しだら前の[a,b,c,d,e]が参照でぎなぐなるでねーが。
リストの中身(a,b,c...)をコピーする必要はねーが入れ物は新しいものを用意しなきゃならねー。
的外れだと言いながら堂々と馬鹿言うでねーよ。
ttp://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2.1
sicpで悪いがfig2.4にリストの実態があるでよ。中身が下段のブロックで、入れ物は上段の2個ブロックだ。
リストの一部更新をする場合、入れ物を元のリストと同じ数だけ作って、中身を指し示す先をちょっと弄るだげだ。
0902デフォルトの名無しさん
2011/02/17(木) 21:04:38フォローに感謝する
0903デフォルトの名無しさん
2011/02/17(木) 22:06:23あるリストから一部変更したリストを作成する場合、一般的には
・ コンスセル(コンテナ、データコンストラクタ(:))の中身を書き換えるだけで足りるとは限らず、たいていは新しいコンスセルが必要。よって、>>898は間違い。
・ 既存のコンスセルと同じ数のコンスセルが必要とは限らず、たいていはそこまでの数は必要ない。よって、>>901も間違い。
0 : 1 : 2 : 3 : [] というリストがあるとするだろ。
これの二番目の要素を5に書き換えた新しいリスト、つまり 0 : 5 : 2 : 3 : [] を生成するとする。
この場合、 0 : 1 : 2 : 3 : [] と 0 : 5 : 2 : 3 : [] の後半 2 : 3 : [] はコピーする必要も新規作成する必要もない。
そのまま参照先として共有できる。少なくとも、参照透明なHaskellではそう。
だから、新しいコンスセルを強調すると 0 『:』 5 『:』 2 : 3 : [] で、この場合、新しいコンスセルは、二つ必要。
必要なコンスセルはゼロでも、四つでも、五つでもない。
二つ。
0904デフォルトの名無しさん
2011/02/17(木) 22:50:440905デフォルトの名無しさん
2011/02/17(木) 23:51:41これ思い出したわ
0906デフォルトの名無しさん
2011/02/18(金) 02:04:06プロファイルとって何処がヒープ使ってるのかがわかっても、いったい何故なのかがわからないから
直しようがないという……
いやこれだけじゃ回答しようがないとは思うんですが、実際原因に検討すらつかないから相談も難しい。
0907デフォルトの名無しさん
2011/02/18(金) 07:10:00可能性の話しかできないけど。
とくに思い当たる節がないのなら、リストのクロージャが大変なことになっているのかもしれない。
リストの操作を手書きでできるだけ一個のfoldrにまとめたらうまくいくか、それに取り組むことで原因が分かるかもしれない。
0908デフォルトの名無しさん
2011/02/18(金) 07:17:12下記のサイトの最新記事(第45回 GHCの性能測定機能でボトルネックを探す)を参考に、
もう少し詳しい検査をしてみるとか
http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248215/?ST=ittrend
0909906
2011/02/18(金) 13:13:18誰か親切な人、軽いヒントだけでいいのでください。
ttp://codepad.org/WBOniwhN
(ICFP 2006の問題)
total alloc: 777,686,388 bytes
parseInst関数: alloc 20%
setRegVal関数: alloc 26.1%
spinCycle-newm(SCC): alloc 17.1%
>>907
ありがとうございます。
リストを捨ててData.Sequenceにしたら少しマシになりました。
>>908
SCCって初めて知りました。
便利なので今試してます。
ありがとうございます。
0910Perl忍者 ◆M5ZWRnXOj6
2011/02/18(金) 14:03:19みんな、おやつは何んですか?
0911デフォルトの名無しさん
2011/02/18(金) 14:53:190912デフォルトの名無しさん
2011/02/18(金) 14:54:37俺はそう思う。
0913Perl忍者 ◆M5ZWRnXOj6
2011/02/18(金) 15:09:39Haskell読書会に出たものの、どうしてもHaskellのソースは読めなかったけれど、
JavaScriptで置き換えてくれてようやく、Haskellが分かった気がした。
なんでjavascriptやてるやつがわざわざ,Haskellやって
まわりの奴がjavascriptで置き換えてあげないといけないの?
ばかなんじゃないの?
こいうやつは、すぐハテナの影響うけて いろいろな言語わめきだすやつだろうwっっっっっっっっっっっっっっっw
0914デフォルトの名無しさん
2011/02/18(金) 16:25:07Sequenceの代わりにIOArrayを使い、全体を StateT UM IO みたいなモナドにして、手続き的に処理するようにすれば改善するじゃないかと思う。
Haskellで手続き的にするのはどうなのよ、という気もするし、場合によっては性能が悪化すると思うけど、おそらく出題が手続きを前提としているので、この場合は改善するんじゃないかな。
0915909
2011/02/18(金) 18:17:37ありがとうございます。
それだと確かにSequence.update使ってる辺りが軽くなりそうですね。
ただ、parseInstはそれだと変わらない気がします。
(というかparseInstみたいな単純な関数がどうしてこんなメモリ食うのかわからないです)
0916デフォルトの名無しさん
2011/02/18(金) 18:30:05Instの各フィールドを!付きのstrictなものにするとか?
0917Perl忍者 ◆M5ZWRnXOj6
2011/02/18(金) 19:42:25晩御飯の時間だよ
0918909
2011/02/18(金) 20:46:12>>916
ありがとうございます。
Word#がよくわからなかったのでとりあえずInstの全フィールドをstrictにしましたが
多分何も変わってない感じです。
0919デフォルトの名無しさん
2011/02/18(金) 21:14:400920Perl忍者 ◆M5ZWRnXOj6
2011/02/18(金) 21:18:330921デフォルトの名無しさん
2011/02/18(金) 23:48:10scanl(\a->(++)a.(:[]))[][1..9]
0922918
2011/02/19(土) 00:02:41Before: 500MBとかメモリ食べて事実上途中でフリーズ(私のPCの空き物理メモリほぼ全部)
After: 10-30MB程度。
(このプログラム(仮想マシン)が未完成なので正常動作しているのかは不明ですが、別の仮想データを食わせたら100MB-200MB程度使いはするものの
前より先まで計算が進んだので状況が改善しています)
以下、参考までに。
1,{-# LANGUAGE BangPatterns #-}をソース先頭に追加。
2,UMとInstのフィールドそれぞれに!を付けた。InstのWord32は{-# UNPACK #-}つき。
3,setRegValの定義をsetRegVal m ra !vに変更。
4,opAMEND内のletのnewvalueとnewarrayの先頭に!追加。
#codepadのコードっていつまで残るのかな?後でこのレス読む人の参考になるといいんですが。
あとこの場合、メモリ使用量の点ではSeqじゃなくてUArrayもありかもと言われました。
更新速度は当然落ちるみたいですが。
プログラム自体は正常動作しているのか不明ですがメモリ使用量は改善しました。
ありがとうございました。
0923みなみな ◆dEQBXko0pE
2011/02/19(土) 09:00:170924デフォルトの名無しさん
2011/02/19(土) 15:52:34その方法で改善する理由も教えてもらった?
0925Perl忍者 ◆M5ZWRnXOj6
2011/02/19(土) 19:16:26Tsuwabuki「僕は、Catalystやってますよ wiki程度ならつくれますが」
俺「へぇ〜wwすごいねえwすごいよw そうなんだあw」
Tsuwabuki「DBIとかわかりますよ」
俺「ほ〜wすごいねえ まじ?w haskellやってるのにPerlもできるんだねえw」
とか話きいてたやったけどさあwwwwwwwwwwwwwww
こいつカスだよwwwwCatalystとかわめいててwwww
そしたら俺を上から目線でみてきて、連絡こなくなったしさww
自分のほうがレベル高かったからおちょくってやったよ
0926Perl忍者 ◆M5ZWRnXOj6
2011/02/19(土) 19:17:43Tsuwabukiから連絡きたんだよwwwwwタイミング的にあれだしw
ハンネぐぐったらhaskellやってるとかツイッターでてきたしさw
ここ見てるやつはTsuwabuki確定だよwwww
0927デフォルトの名無しさん
2011/02/19(土) 19:21:30使い分けは
モナド適用前:foldM
モナド適用後:onM
onM f a [] = a
onM f a (x:xs) = onM f (do{y<-a;f y x}) xs
onM (\acc x -> return (x acc)) (Just 1) [(*2),(*3),(+1)]
foldM (\acc x -> Just $ x acc) 1 [(*2),(*3),(+1)]
0928Perl忍者 ◆M5ZWRnXOj6
2011/02/19(土) 19:29:13やめちまえ
論理家きどってんじゃねえぞかす
0929918
2011/02/19(土) 20:07:29.55IOVector(Unboxed)+unsafeRead,unsafeWrite等にしたらメモリ消費量も少なくアクセス、更新共に速い。
(ただしIOモナドだらけに。そしてモナド内でのwriteがなんか気持ち悪い。)
データ構造の選び方次第でも全く速度やメモリ消費が違うんですね。
無視できない差です。
>>922
ききませんでした。
0930デフォルトの名無しさん
2011/02/19(土) 20:07:35.110931デフォルトの名無しさん
2011/02/19(土) 21:28:06.07最近発表されたhashing-based containerのスライドでも更新時のArrayのコピーが他の改善点をぶち壊すぐらいのネックになってたし
この辺に関して堅牢さを保ったまま速度を出す方法とかあんのかな?
Haskellの型システムの中で線形型システムを作ってそれでIO地獄を隠蔽するとかぐらい?
bound checkに関してはそれこそstatic contractionとかdependently typeみたいなformal method方面のやりかたを導入するしか無さそう
0932デフォルトの名無しさん
2011/02/19(土) 21:55:47.35線形型で実現された配列と比べたら柔軟さで劣るけどHaskellの型システムの枠内ですぐに使える
Arrayのコピーは単純にGHCのrtsのチューニングでなんとかなるんじゃないかと期待
0933デフォルトの名無しさん
2011/02/19(土) 21:56:43.030934デフォルトの名無しさん
2011/02/20(日) 03:10:56.66UArray は、たぶん更新ごとに配列全体をコピーしていると思うので、そりゃ、遅い。
優良生産者、優良消費者でうまく組み合わせていれば、最適化されるかもしれないけど。
この点については、オレはまだ試してないけど、http://itpro.nikkeibp.co.jp/article/COLUMN/20101013/352848/?ST=ittrend で紹介されている手法が、うまく動くかもしれない。
ただ、>>909 の課題自体、手続的な概念によっているんじゃない?
そうであれば、性能関係なく、IOモナドを含むStateモナド系で状態を隠蔽するのが、概念的にもスマートなプログラミングなのではないか、という気がする。
0935デフォルトの名無しさん
2011/02/20(日) 10:32:47.06Haskellから呼び出すってできないの?
0936デフォルトの名無しさん
2011/02/20(日) 11:20:26.15呼び出すだけなら簡単にできる
双方のメモリアドレスの受け渡しが絡んでくると、扱いが面倒になるが
0937デフォルトの名無しさん
2011/02/24(木) 19:48:57.42test = do w <- [1..(10)]
v <- (\x -> [x,x^2]) w
guard $ (\x -> x `mod` 2 /= 0) v
return v
これをdo構文を使わずに書くことは出来るのでしょうか。
そもそも3行目の有無でtestの値が変わる仕組みがよく分かりません。
return v の代わりに return w とした結果もどうしてこうなるのか?という感じで…
0938デフォルトの名無しさん
2011/02/24(木) 20:30:46.27test3=[1..10]>>=(\w->(((\x->[x,x^2]) w)>>= (\v->(guard $ ((\x -> x `mod` 2 /= 0) v)) >> return v)))
guardがやっているのは、条件を満たす個数だけ要素を残すことなので、結果は何でもいい
[1..10] >>= (\x->guard (x<5))は
[(),(),(),()]
Listモナドの>>=動作はconcatMapだが
>>でつないだときは、前の要素数分、新しい要素を作ってconcatMap
[1,2,3] >> [4,5]も
[(),(),()] >> [4,5]も
[4,5,4,5,4,5]
そして、
do記法で単に{ a;b;c}ってのはa>>b>>cと同じ意味
同じ内容ならこんな感じで
[x|x<-[1..10]>>=(\a->[a,a^2]),rem x 2/=0]
0939デフォルトの名無しさん
2011/02/24(木) 21:08:50.21> そもそも3行目の有無でtestの値が変わる仕組みがよく分かりません。
> return v の代わりに return w とした結果もどうしてこうなるのか?という感じで…
次の定義をどこかにメモっておいて、
自分でノートなんかに >>= の式を展開してみると、
より理解が深まる(かも知れない)
-- GHC.Base より
instance Monad [] where
m >>= k = foldr ((++) . k) [] m
m >> k = foldr ((++) . (\ _ -> k)) [] m
return x = [x]
fail _ = []
-- Control.Monad より
instance MonadPlus [] where
mzero = []
mplus = (++)
-- Control.Monad より
guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero
0940デフォルトの名無しさん
2011/02/24(木) 22:16:47.71オレはリストモナドを平行世界的に理解している。
test = do
w <- [1..(10)] -- {w = 0}の世界、{w = 1}の世界、{w = 2}の世界・・・、{w = 10}の世界の世界が生まれる
v <- (\x -> [x,x^2]) w --
guard $ (\x -> x `mod` 2 /= 0) v
return v
0941940
2011/02/24(木) 22:23:42.21test = do
w <- [1..(10)] -- {w=1}の世界、{w=2}の世界・・・、{w=10}の世界の世界が生まれる
v <- (\x -> [x,x^2]) w -- {w=1, v=1}, {w=1, v=1}, {w=2, v=2}, {w=2, v=4}・・・の各世界に分岐
guard $ (\x -> x `mod` 2 /= 0) v -- {w=2, v=2}, {w=2, v=4}・・・ などが失われる
return w -- {w=1, v=1}, {w=1, v=1}, {w=3, v=3}, {w=3, v=9}・・・ などの世界が生き残っている
いちめん染める花は♪ 空へと昇る光♪
幾億の息吹たち♪ 今♪ 世界が生まれ変わる〜♪
0942デフォルトの名無しさん
2011/02/24(木) 23:57:02.76gfxが一瞬で倒せる領域、もう神の世界
君たちHaskellは、天界から下界を見て広大な心で迎え入れているのだろう
0943デフォルトの名無しさん
2011/02/24(木) 23:58:18.260944デフォルトの名無しさん
2011/02/25(金) 00:11:34.58君たちは、ハスクカルド天界、モナド聖騎士団っていう登場キャラで出してあげるから
おとなしくしてね
0945デフォルトの名無しさん
2011/02/25(金) 00:24:00.510946937
2011/02/25(金) 01:01:24.13皆さんありがとうございます。
色んな方から視点を貰えて助かりました。
なんとか全て理解できた気がします。
後は慣れじゃー
0947デフォルトの名無しさん
2011/02/25(金) 07:51:46.590948デフォルトの名無しさん
2011/02/25(金) 11:01:13.140949デフォルトの名無しさん
2011/02/25(金) 11:31:34.420950デフォルトの名無しさん
2011/02/25(金) 15:24:18.70条件を満たすすべての組み合わせを列挙する、ということが自然に表現できるよね。
>>948
Linuxのディストリビューションとかだと、その辺はパッケージャーが考えること、という気もする。
ただ、実際には、UbuntuのGHCパッケージの放置されっぷりといったら・・・
他のディストリビューションだとどうなのかは知らん。
0951デフォルトの名無しさん
2011/02/25(金) 16:08:33.060952デフォルトの名無しさん
2011/02/25(金) 16:35:34.38大規模な開発だとライブラリの後方互換性は重要な問題だと思うけど
>>950
言語(コンパイラ)仕様がディストリだのパッケージメンテナだのといった存在に依存してるのはおかしいと思う
せっかくネイティブコード吐けるのに、
I/Fを弄らずにライブラリを改変してもバイナリコンパチが崩れるのは、言語として幅を狭めているのでは
0953デフォルトの名無しさん
2011/02/25(金) 19:09:31.16Haskellはある程度激しい最適化をしないと使い物にならないことが多いから、
バイナリ互換性を崩してパッケージ間インライン化を取るのは仕方ない取引だと思う
0954デフォルトの名無しさん
2011/02/25(金) 19:58:48.79激しい最適化はストリームフュージョンとかの中間言語レベルの時だと思うんだが
まぁ、中間言語のファイルをやりとりすることは無く、
実質バイナリ互換性を崩してるという話はその通りなので >>953 には同意する
0955デフォルトの名無しさん
2011/02/25(金) 20:45:58.12みたいなオプションは有り得るよな
0956デフォルトの名無しさん
2011/02/25(金) 22:29:11.60それから、モジュール中の全ての演算に無条件に正確性を強制するオプションがあってもいい。
0957デフォルトの名無しさん
2011/02/28(月) 00:53:10.20さっき、Haskell Platform の最新版をインストールしたんですが、
Text.Regex.Posix の (=~) の [String] ってなくなったんでしょうか?
↓ みたいなのができなくなってました
"test" =~ "t" :: [String]
Windows7 64ビットです
0958デフォルトの名無しさん
2011/02/28(月) 01:46:22.12regex-posixパッケージを本格的に使ったことないけど、最新の0.94.4ではダメみたいね。
想像するに
getAllTextMatches $ "test" =~ "t" :: [String]
にとって代わられたのかしら。
0959デフォルトの名無しさん
2011/02/28(月) 02:03:23.98偽りの人生だった
0960デフォルトの名無しさん
2011/02/28(月) 02:38:48.74ワロタ
「偽りの人生」が再帰でないことを祈る
0961デフォルトの名無しさん
2011/03/02(水) 07:20:26.91cabal info gtk2hs-buildtools で確認したところ、
Latest version available: 0.12.0
Latest version installed: [ Unknown ]
と表示されたのですが、これは正しくインストールされたのでしょうか。
未インストールの状態なら、普通は [ Not installed ] と表示されると思うのですが、
[ Unknown ] はどのような状態なのでしょうか。
0962デフォルトの名無しさん
2011/03/02(水) 07:35:59.51gtk2hsC2hs、gtk2hsHookGenerator、gtk2hsTypeGenっていう三つのコマンドが入っていれば、インストールされているんじゃないの?
0963デフォルトの名無しさん
2011/03/02(水) 08:01:34.32qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
は、==のテストが冗長な気がするのですが
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (x <) xs)
として大丈夫ですよね?
0964デフォルトの名無しさん
2011/03/02(水) 08:15:23.44入力リストの要素に重複がないなら同じだと思うけど、前者はそれがある場合に備えているわけで、べつに冗長ではないのでは?
0965デフォルトの名無しさん
2011/03/02(水) 08:24:50.94List.nub+qsortを混ぜたような処理になるわけか
0966デフォルトの名無しさん
2011/03/02(水) 08:30:45.27ありがとうございました
0967デフォルトの名無しさん
2011/03/02(水) 12:43:09.98filter で2回もリストを辿ることに冗長性は感じないのかな
0968デフォルトの名無しさん
2011/03/02(水) 20:59:11.07q[]=[]
q(x:xs)=arr (List.partition(<x))>>>first q >>> second q>>>arr((((((((((((((app .).).(&&&))(((app .).).(&&&)) (const id)).).).).)((flip.).) ((.).((.).))) .).).).) (((.).(.)).)flip(++)(:) x snd fst ) $ xs
0969デフォルトの名無しさん
2011/03/02(水) 21:02:26.750970デフォルトの名無しさん
2011/03/02(水) 21:07:12.68テラワロスwww
どれくらい時間かかった?
0971デフォルトの名無しさん
2011/03/02(水) 21:10:05.55やだ変態っ!
0972デフォルトの名無しさん
2011/03/02(水) 21:27:24.310973デフォルトの名無しさん
2011/03/02(水) 21:31:20.541時間もアロー、アローでゴシゴシやってたのかwww
オマエみたいな変態は大好きだwww
研究室にはいらない。
0974デフォルトの名無しさん
2011/03/02(水) 22:45:38.880975デフォルトの名無しさん
2011/03/02(水) 22:50:12.88お前、墓碑銘それにしなよ
0976デフォルトの名無しさん
2011/03/03(木) 06:33:18.64if' b x y = if b then x else y
qs :: Ord a => [a] -> [a]
qs = fix (ap (flip if' [] . null) . ap (ap . ((++) .) . (. ap (filter . flip (<) . head) tail)) (ap ((++) . return . head) . (. ap (filter . flip (>=) . head) tail)))
0977デフォルトの名無しさん
2011/03/03(木) 23:40:57.17保守しにくい
教育しにくい
絶対に純粋さが裏目に出てる
0978デフォルトの名無しさん
2011/03/04(金) 00:06:14.650979デフォルトの名無しさん
2011/03/04(金) 00:28:00.710980デフォルトの名無しさん
2011/03/04(金) 07:42:12.400981デフォルトの名無しさん
2011/03/04(金) 17:59:55.900982デフォルトの名無しさん
2011/03/04(金) 18:06:31.100983デフォルトの名無しさん
2011/03/04(金) 21:04:50.350984デフォルトの名無しさん
2011/03/05(土) 19:23:50.93誰かなんかしたのか?
0985デフォルトの名無しさん
2011/03/05(土) 22:18:14.150986デフォルトの名無しさん
2011/03/06(日) 08:17:42.160987デフォルトの名無しさん
2011/03/06(日) 10:41:43.33じゃぁ、mapはListの(a->b)->[a]->[b]であるべきか、それともfmapの異名としてFunctor f=> (a->b)->f a->f bにしてしまうべきか。
0988デフォルトの名無しさん
2011/03/06(日) 10:49:09.370989デフォルトの名無しさん
2011/03/06(日) 12:26:36.46俺は map の型を Functor f=> (a->b)->f a->f b にして、
全部これで統一して(fmap 要らん)たら良かったと思う
分ける事で構文的にあるいは意味論的に美しくなるとも思えないから、
2つもあるのは冗長にしか感じない
であれば、fmap なんて一般的じゃない名前より map に統一してほしい
まぁ今更もう遅すぎるが
0990デフォルトの名無しさん
2011/03/06(日) 12:45:35.950991デフォルトの名無しさん
2011/03/06(日) 12:59:23.13(:[])をreturnと書くのと同種の趣味の悪さを感じる
fmapという名前が気に食わないなら(<$>)という素晴らしい名前があるよ
(<$>)をPreludeに入れるべきという提案なら賛成する
0992デフォルトの名無しさん
2011/03/06(日) 13:25:36.32対象関数と射関数が必要だからfmapは必要だと思う。
無いとしたらどうやってFunctorクラスを特徴付ける?
0993デフォルトの名無しさん
2011/03/06(日) 13:29:57.20989が言っているのは、リスト専用のmapは廃止し、Funtorのfmapをmapに改名して、リストの場合も後者を使えばよい、ってことでしょ。
0994デフォルトの名無しさん
2011/03/06(日) 13:33:44.07あと、新スレ立てといた
http://hibari.2ch.net/test/read.cgi/tech/1299385928/
0995994
2011/03/06(日) 13:37:55.32リンク先が落ちてないか調べるの面倒なんだが
0996デフォルトの名無しさん
2011/03/06(日) 13:41:25.90スマソ。そういうことか。
0997デフォルトの名無しさん
2011/03/06(日) 13:45:10.46そうでない初心者がいきなりfmapを使いこなすのは(mapと比べて)難しいんじゃないかと。
Haskellへの門戸を大きく開く意味で、現状の命名法は悪くないと思うんだけどな。
0998デフォルトの名無しさん
2011/03/06(日) 13:58:44.78であれば、
map :: Functor f=> (a->b)->f a->f b
lispMap :: (a->b) -> [a] -> [b]
lispMap = map
こんな感じでいいんじゃないか?
listMap は map をリストの型に特殊化したものなんだけど、
とりあえずはそんな深く考えずに、リストでは listMap を使っておいてね
あとで Functor の意味が分ってきたら汎用性のある map を使っていこう
と言っておけば
0999デフォルトの名無しさん
2011/03/06(日) 14:11:29.55テンプレが肥大化したスレの場合、どっかのフリーなwikiにページを作って
アウトソーシングしたりしてるのをたまに見かける。
1000デフォルトの名無しさん
2011/03/06(日) 14:36:45.83関数定義の内容はどうでも良くて(初心者は関数を使いこなすのが精一杯だから)、
関数の命名法、名前の付け方を言ってるんだけどな。
初心者の常識にズレが少ない、配慮(心配り)という意味で。
少なくともリストというデータ構造は関数型言語の基本であり、ありふれて利用されている。
だからそんなリスト向けにはmapという命名を、理論的には汎用性があっても
初心者には難解な関手向けにはFunctor mapという命名にするのは悪くはないんじゃね。
10011001
Over 1000Threadもう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。