関数型プログラミング言語Haskell Part9
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/05/17(土) 16:41:29http://www.haskell.org/
日本語サイト
http://www.sampou.org/cgi-bin/haskell.cgi
http://www.shido.info/hs/
過去ログ
関数型プログラミング言語Haskell
Part1 http://pc.2ch.net/tech/kako/996/996131288.html
Part2 http://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 http://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 http://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 http://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 http://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 http://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 http://pc11.2ch.net/test/read.cgi/tech/1193743693/
・2chの仕様により、行頭の半角スペースは表示されません。
コードをインデントしたいときは、代わりに または全角スペースを使うことができます。
0412デフォルトの名無しさん
2008/08/09(土) 13:08:180413デフォルトの名無しさん
2008/08/09(土) 13:13:08動的型を使うと、アドホックなエラー処理が必要になるよね?
っていうか、それがないと動的型を使ううまみがないと思うんだけど。
ここでいうアドホックなエラー処理っていうのは、
対象オブジェクトの型をプログラムで認識して、
意図しないオブジェクトが来たときにエラー処理するってことだけど。
このエラー処理にIOを使わないなら、
それは多相型やクラスを使っても同じ結果が得られるよね。
だから、Haskellに動的型を組み込む必要性は、
意図しないオブジェクトが来たときIOを使ったエラー処理をしたいときに限られると思う。
で、純粋関数型言語は参照透明性ゆえにIO処理するの苦手。
まぁ、動的型っていうのはプログラム中で型を認識できないと意味ないよね?
っていう時点で、カリー・ハワード対応との関係で微妙っていう気にするけど。
僕が考えているのは、そんな感じ。
0414デフォルトの名無しさん
2008/08/09(土) 13:17:44Haskellに多いやつらの典型だなw
0415デフォルトの名無しさん
2008/08/09(土) 13:18:59動的でマルチパラダイムな言語で書いたのと同じになる。
0417デフォルトの名無しさん
2008/08/09(土) 13:50:48せいぜい生きる力を養ってください
0418デフォルトの名無しさん
2008/08/09(土) 13:54:52implementationの本を読むといいよ
Peyton Jonesのがpdfで読めるはず
0419デフォルトの名無しさん
2008/08/09(土) 14:11:34俺はPJのが好きだな。
静的型付けとグラフ簡約が運命的な出会いであることがわかった。
0420デフォルトの名無しさん
2008/08/09(土) 14:19:55なんか議論が無茶苦茶じゃないか?
例えば「型エラー」を「0除算エラー」に置き換えても論理展開が変わらん
>このエラー処理にIOを使わないなら、
>それは多相型やクラスを使っても同じ結果が得られるよね。
動的型の重要な利点は、型をいちいち書かなくてもいいという利便性だよな
多相型やクラスを使って動的型をシミュレートするのはすごく面倒だから、この利点を享受できない
それから、GHCではerrorやundefinedで発生したエラーをIOモナド上で捕捉できる。念のため
0421デフォルトの名無しさん
2008/08/09(土) 14:26:59あと、動的型のメリットを例外処理だけに限定するのは視野が狭すぎる。
LISPのメリットはアドホックな例外処理か?そうじゃないと思う。
0422デフォルトの名無しさん
2008/08/09(土) 14:39:32納得できないのなら、それで良いです。
僕も、べつにそんなに優れた論拠だと思ってないから。
0423デフォルトの名無しさん
2008/08/09(土) 14:55:35>>416が理解したのが驚愕。
0424デフォルトの名無しさん
2008/08/09(土) 15:20:10すげえ
0425394
2008/08/09(土) 15:22:47それだけであれば、コンパイルで発見する不具合をテスト時に見つけよう
とする、つまり面倒なことを後回しにしてるだけ、ってことになりませんか?
0426デフォルトの名無しさん
2008/08/09(土) 15:23:150427デフォルトの名無しさん
2008/08/09(土) 15:30:45S式なんて最たるもので、静的な型付けは不能あるいはワイルドカード的。
静的か動的かはトレードオフの問題。
0428デフォルトの名無しさん
2008/08/09(土) 15:42:04不具合を見つけるタイミングが遅くなるという対価を払って、記述の利便性および変更の容易さという報酬を得る
ちゃんと取引として成立してるじゃないか
もちろん「型を書かなくて済む」こと以外にも利点はある
特定の静的型付け言語ではそもそも型を付けられないようなコードが許容されるとか
0429デフォルトの名無しさん
2008/08/09(土) 17:38:51lispを使ってる限りの印象だが
都合のよい所だけ型宣言が出来るというのは柔軟性につながるかな。
プログラムの最適の仕方も静的/動的で違いがあると思うよ。
型なんで考えずにアルゴリズムだけ作っちゃえができるからね。
それでも型を意識したプログラミングをすることはあるが。
でも、haskellでもポリモつかえばある程度型無視ラピッドプログラミング
は可能じゃないか?
0430デフォルトの名無しさん
2008/08/09(土) 17:41:420431デフォルトの名無しさん
2008/08/09(土) 17:44:14haskellって参照透明性ってかなりのメリットだと思ってるけど。
0432デフォルトの名無しさん
2008/08/09(土) 17:49:41Hashkellはメリットを殺すデメリットしかないだろ
0433デフォルトの名無しさん
2008/08/09(土) 17:56:37http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types
0434デフォルトの名無しさん
2008/08/09(土) 17:57:26OCamlはstrictだから。残念。
0435394
2008/08/09(土) 19:55:26コンパイル時に問題が抽出されることと、テストによって抽出されるのでは
質的な違いがあるんじゃないですか?テストは結局は人間がやるものだし、
不具合の可能性を低めるということにしかならないけど、コンパイルでの
不具合検査は対象となるプログラムの論理的正しさを証明していることに
なるかと思います。
容易に変更ができたとして、不具合がどこに潜んでいるのか分かりにくい
というのは非常に問題あると思いますよ。コンパイルで分かるのならば、
これは明白でしかも機械的に全てが晒されますから安心です。
0436デフォルトの名無しさん
2008/08/09(土) 20:20:59そんざいしないしな
0437デフォルトの名無しさん
2008/08/09(土) 20:23:09確かに、バグがどの段階で発見されるかには質的な違いがある
でも、静的な型検査だって全てのバグを検出できる訳じゃないから、
結局、動的検査との安全性の違いは程度問題
その上で、静的な型検査の利点がコストを上回るという判断は当然ありえるし、
そう判断したなら静的型言語を使えばいい
0438デフォルトの名無しさん
2008/08/09(土) 20:28:12静的型チェック馬鹿ですやん
0439394
2008/08/09(土) 20:39:50例えば、参照透明ということについてはどうでしょうか?こちらも、副作用を許容
すれば、プログラム中に登場する変数の中身が何に変異しているかどうかが
分からなくなり、実行してみないと問題が検出できない、ということになります。
参照透明を強要するのも、型を強要するのも、結局その辺がクリアできない
プログラマというのはそれらに関連する不具合を出してしまうんだと思いますが
どうでしょうか。気をつければいい、というのは簡単で規模が小さなシステムでは
言えることで、そうでなければ膨大なテスト工程が必要になってしまうのでは?
0440デフォルトの名無しさん
2008/08/09(土) 20:46:48refとかで破壊的な変数が作れるから嫌とかそういうレベルの話じゃないよね。
それだったらref使わなければいいだけだから。
逆に、Haskellの参照透明で良い所ってどのへんなの?
OCamlのでも、ErlangのでもなくHaskellの参照透明性が良い理由を説明してほしいんだが。
0441394
2008/08/09(土) 21:04:32参照透明でない、ということは値が望んだ通りの値であることを
保証するためにどこまでも神経質にテストをしなければならない、
ってことですよね。
一人で開発するのであればいいですが、多くの人の手によって
間違いがあってはならないシステムの開発をする際、「それは
禁じ手だから止めてね」と口約束するだけってのは非常に怖い
わけです。だからこそ、テストの工程が膨れ上がる。
Haskellに自分が惹かれている大きな理由の一つは、この辺の
頑固さを貫いていることですね。
0442デフォルトの名無しさん
2008/08/09(土) 21:19:02それだけでテストが必要なくなるわけでも、
テストが簡単になるわけでもない。
そうなるのはトイプログラムだけ。
嘘だと思うなら、GHC, Hugsなどのバグトラックをみてみればいい。
0443デフォルトの名無しさん
2008/08/09(土) 21:21:510444437
2008/08/09(土) 21:22:55何が言いたいのか良く分からん
俺は「気をつければいい」なんて一言も言ってないよ
>>428に書いたように、動的か静的かの間でトレードオフが成立すると言っているだけ
>>441
OCamlの変数は変更不可だよ
変更できるのは参照(ref)で、これは変数とは別物
だから、口約束するまでもなく変数の値が変わらないことは保証されてる
0445デフォルトの名無しさん
2008/08/09(土) 21:26:07参照透明性を壊さないと入出力できないのが嫌
044636 ◆K0BqlCB3.k
2008/08/09(土) 21:37:36数学的に無理だから、統計的に証明するわけですよ。
実際に〜〜でした、ってね。
ヒューマンインターフェース系の論文が参考になるんじゃないかな。
あっちは全部そんな感じ。
0447デフォルトの名無しさん
2008/08/09(土) 21:38:56Haskellでもやろうと思えばIORefとかで事実上破壊的な操作が可能になるわけですが、
これについてはどうお考えで?
「HaskellでIORefは使うな」っていうプログラミングルールを設定することは
「OCamlでref使うな」っていうルールを設定することと本質的に違わないと思うんだけど
それについてはどうなんすか。
044836 ◆K0BqlCB3.k
2008/08/09(土) 21:40:14どう見てもアクリル製のガワの中に反射板入れただけやん。
UFOとかエイリアンとか、考古学じゃなくてSFやん。
突っ込みどころ満載な映画でした。
かしこ
0449デフォルトの名無しさん
2008/08/09(土) 22:13:11したいです。どこがいい問題集頂戴
0450デフォルトの名無しさん
2008/08/09(土) 22:23:39do記法を使わずにliftM、liftM2、joinを実装
Continuationモナドを実装
045136 ◆K0BqlCB3.k
2008/08/09(土) 23:30:03また何も考えずにそういうこと言う。
>>449
http://ja.doukaku.org/
045236 ◆K0BqlCB3.k
2008/08/09(土) 23:31:04http://projecteuler.net/
0453デフォルトの名無しさん
2008/08/10(日) 05:05:51モナドとλの練習なら>>450はいい案じゃないか。
いっぱいじゃないけど質的にいい。
0454デフォルトの名無しさん
2008/08/10(日) 05:08:55>>419
PJのって何?本もpdfもPJのでしょ?
0455デフォルトの名無しさん
2008/08/10(日) 08:02:29Implementation of Functional Programming
Implementing Functional Languages,(D. Lesterと共著)
を書いていて両方公開。
http://www.haskell.org/haskellwiki/Books
0456デフォルトの名無しさん
2008/08/10(日) 08:05:37http://www.haskell.org/haskellwiki/Tutorials
0457デフォルトの名無しさん
2008/08/10(日) 13:23:16すまん、>>455のImplementing...のほうを言いたかった。
045836 ◆K0BqlCB3.k
2008/08/10(日) 13:39:12>>449は本当にモナドとラムダの練習のためだけに問題をほしがっているのかどうかってこと。
それに、初心者は何か目に見えて動かせるものを書きたがるものさ。
誰かに見られることを想定して書くのと、「動けばそれでいい」だけで書くのとでは、
やっぱり前者の方がいろいろ調べたりすることで勉強になる。
0459デフォルトの名無しさん
2008/08/10(日) 15:23:20そこ載ってなくね?w
http://research.microsoft.com/~simonpj/Papers/slpj-book-1987/index.htm
http://research.microsoft.com/~simonpj/Papers/pj-lester-book/
>>457
サンクス。目次しか見てないけど、
Implementationがパターンマッチや型など広く扱ってて、
Implementingはコンパイラのコアな部分を主に扱ってる感じ?
静的型付けとグラフ簡約の運命的な出会いというからそうでもない?
まあImplementingのほうを読んでみます。
>>458
そうですね。
0460デフォルトの名無しさん
2008/08/10(日) 16:23:15グラフ簡約と運命的な出会いというと遅延評価じゃないかね。
特にPJ的には。
0462419
2008/08/11(月) 14:44:370463デフォルトの名無しさん
2008/08/11(月) 16:05:22あまり理解できてなかったんじゃない?w
0464デフォルトの名無しさん
2008/08/11(月) 16:13:31かもしれない。
できれば君が読んでポイントだと思ったところを挙げてくれると皆の参考になると思う。
0465デフォルトの名無しさん
2008/08/11(月) 16:20:35例え動的型チェックをやろうとも、そのコードは、
他の普通のコードと一緒でスーパー・コンビネータになって、
グラフ簡約されるだけだから、コンパイル時に型チェックを済ませることが、
スーパー・コンビネータのグラフ簡約上、特に有利だとは思えません。
0466デフォルトの名無しさん
2008/08/11(月) 17:39:550467デフォルトの名無しさん
2008/08/13(水) 09:02:330468デフォルトの名無しさん
2008/08/13(水) 10:48:150469デフォルトの名無しさん
2008/08/13(水) 11:17:46MonadCont の callCC :: ((a -> m b) -> m a) -> m a のことじゃないの。
>>467
俺も気になる。違いはあるだろうけど、どう違うのか。
0470デフォルトの名無しさん
2008/08/13(水) 11:23:16作るとしたら、ステートモナドに次のアクション
入れておくとかですかね。
0471デフォルトの名無しさん
2008/08/13(水) 13:45:50# mfixとか使えば別だけど。
例えば、Schemeで次の式は書けるが、MonadContでは書けない。
(call/cc (lambda (c) c))
(call/cc (lambda (c) (set! foo c)))
つまり、次の式は型が付かない。
callCC (\c -> return c)
callCC (\c -> lift $ put c)
要は、callCCで捉えた継続をそのcallCCの外に出せない。ただし、
callCC (\c -> ... callCC (\c' -> c c') ...)
のように、内部で別のcallCCを使って、それで捉えた継続を外に出すのはOK。
あと、変な例として、
callCC (\c -> return (Right (c . Left)))
はOK。でもやっぱり無限ループはできない。
0472デフォルトの名無しさん
2008/08/13(水) 14:58:55だとすると、smlのcall/ccを使ったco-routineみたいなことはできないということ?
0473デフォルトの名無しさん
2008/08/13(水) 17:43:19import Control.Monad.Cont
foo = callCC (\c0 ->
do
c1 <- callCC c0
c2 <- callCC c1
c2 10
undefined)
bar =
(do
c1 <- foo
c2 <- callCC c1
callCC c2)
main = print $ runCont bar id
0474デフォルトの名無しさん
2008/08/13(水) 18:18:41HaskellでYコンビネータを書くとき型が問題になるけど、
実質的には fix f = let g = f g in g で問題ない。
それと同じように、
loop = callCC (\c -> let g = c g in return g)
とすれば
do { l <- loop; liftIO $ print 0; l }
のように無限ループを書ける。
(これの変数付きループ版が MonadLib にあった。)
(call/cc (lambda (c) c))
がどう使われるのかよく分からないけど、
実質的には同じことになるんじゃないかな?
(call/cc (lambda (c) (set! foo c)))
callCC (\c -> lift $ put c)
は IORef を使うと問題なくできる。
State だと無理だけど、新しく再帰的なデータ型を定義してやれば、
あまり便利では無さそうだけど一応できた。
0475デフォルトの名無しさん
2008/08/13(水) 22:46:51著者にプレッシャヨロ
047636 ◆K0BqlCB3.k
2008/08/13(水) 22:51:050477デフォルトの名無しさん
2008/08/13(水) 23:21:14んですよね?Haskellではそういうのは無いと思っていいんでしょうか?
0478デフォルトの名無しさん
2008/08/14(木) 00:04:58モナド無しでということなら無い。
そもそもcall/ccは副作用があるし。
0479デフォルトの名無しさん
2008/08/14(木) 13:47:210480デフォルトの名無しさん
2008/08/14(木) 17:35:340481デフォルトの名無しさん
2008/08/14(木) 18:53:400482デフォルトの名無しさん
2008/08/14(木) 18:54:490483デフォルトの名無しさん
2008/08/16(土) 19:35:13http://lethain.com/entry/2008/aug/14/global-popularity-of-programming-languages/
0484デフォルトの名無しさん
2008/08/16(土) 20:24:000485デフォルトの名無しさん
2008/08/16(土) 22:50:09こうゆう落ちもある。
0486デフォルトの名無しさん
2008/08/17(日) 12:30:17http://haskell.org/haskellwiki/Xmonad/Config_archive
の設定ファイル郡を理解できるぐらいまでHaskellについて知りたいんですが
どこから勉強すればいいんでしょう?
知識はXmonadやGhcをソースからインストールできる程度です
0487デフォルトの名無しさん
2008/08/17(日) 13:44:52テストは軽減する。haskellなどはそのことが数学的に証明されているので
プログラマはぬるぽやoutofboundsなどの基本的な間違いにであうことなく、
本質だけを考えることができる。
0488デフォルトの名無しさん
2008/08/17(日) 14:23:37たとえば「空でないリスト」型が欲しいとき、ぬるぽ的な実行時エラーを防げるの?
0489デフォルトの名無しさん
2008/08/17(日) 14:47:05依存型のある言語なら防げるかも知れんけど
0490デフォルトの名無しさん
2008/08/17(日) 15:31:08おまえ初心者スレにいたHaskell信者だろ。
0491デフォルトの名無しさん
2008/08/17(日) 18:08:120492デフォルトの名無しさん
2008/08/17(日) 18:14:59それヘボすぎ
0493デフォルトの名無しさん
2008/08/17(日) 18:26:58誰か教えて下さい
0494デフォルトの名無しさん
2008/08/17(日) 18:36:200495デフォルトの名無しさん
2008/08/17(日) 18:36:410496デフォルトの名無しさん
2008/08/17(日) 18:42:380497デフォルトの名無しさん
2008/08/17(日) 18:59:33ttp://www.sampou.org/haskell/a-a-monads/html/
の以下の部分を読むとわかるかも
Maybe というモナド
ひとつの例
リストもモナド
0498497
2008/08/17(日) 19:11:05の各モナドの利用場面や動機を見るのもいいかもしれない
0499デフォルトの名無しさん
2008/08/17(日) 19:15:59便利だからという理由以外にモナドをIO以外に使う理由はあったりしますか?
それだけの理由で使うには扱いが難しくて、プログラムを組む度に頭がオーバーヒートしそうになる
慣れの問題かそれとも理解不足か・・
0500デフォルトの名無しさん
2008/08/17(日) 19:25:15そこでmaybeもなどですよ。
0501デフォルトの名無しさん
2008/08/17(日) 20:06:22IO, Maybe, List, etcの計算の合成を統一的に扱えるってのが最大の利点なんではないかと。
単に使うだけなら主に慣れの問題だと思う。
いろんな例を見て慣れていけば少しずつ理解もできていくんではないかと。
0502デフォルトの名無しさん
2008/08/17(日) 20:09:490503デフォルトの名無しさん
2008/08/17(日) 20:33:06レス有難うです
慣れの他に密度の問題もあるかもしれないと思ったり。
他の言語より1行あたりの密度が濃いものになりやすい気がする。
というか濃縮されすぎてわけが分からなくなりやすい気がする。
0504デフォルトの名無しさん
2008/08/17(日) 20:38:12計算を統一的に扱うだけであれば、普通の型クラスでいいんですよね?
モナドは値ではなくて型コンストラクタに対するクラスなので、ちょっと違う
と思うんですが。
050536 ◆K0BqlCB3.k
2008/08/17(日) 20:39:51所詮はただの代数的データ型とそのデータ型に対して一貫性あるAPIのセットに過ぎないよ。
ところで、 データ型とAPIのセット のことをなんて呼べばいいの?
0506デフォルトの名無しさん
2008/08/17(日) 20:40:10型クラス(b,s) -> (a,s)に型bを部分適用したって考えれば意味は通るけど……
0507デフォルトの名無しさん
2008/08/17(日) 21:08:43それが「型クラス」、ではないのでしょうか?MonadやFunctorはちょっと
毛色が違うという認識は勘違いでしょうか?
0508デフォルトの名無しさん
2008/08/17(日) 21:17:01Ord、Eq、Show などの データ型とそのAPIのセット は「型クラス」
Functor、Monad、MonadPlus などの データ型の構築子とそのAPIのセット は「型構築子クラス」
0509デフォルトの名無しさん
2008/08/17(日) 21:31:22Functorの『類』は*->*みたいに引数をとる、って違いにしか見えない
分けて考えるのはおかしいと思う
0510デフォルトの名無しさん
2008/08/17(日) 21:37:45型クラスと型構成子クラスじゃ抽象度が違うよ。
0511デフォルトの名無しさん
2008/08/17(日) 21:49:13抽象度が違うのは理解できるが
■ このスレッドは過去ログ倉庫に格納されています