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

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2012/10/17(水) 08:08:28.97
haskell.org
ttp://www.haskell.org/

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

過去ログ
関数型プログラミング言語Haskell
Part1 ttp://pc.2ch.net/tech/kako/996/996131288.html
Part2 ttp://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 ttp://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 ttp://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 ttp://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 ttp://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 ttp://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 ttp://pc11.2ch.net/test/read.cgi/tech/1193743693/
Part9 ttp://pc11.2ch.net/test/read.cgi/tech/1211010089/
Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/
Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/
Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/
Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/
Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/
Part15 ttp://hibari.2ch.net/test/read.cgi/tech/1310199414/
Part16 ttp://toro.2ch.net/test/read.cgi/tech/1317958045/
Part17 ttp://toro.2ch.net/test/read.cgi/tech/1325510368/
Part18 ttp://toro.2ch.net/test/read.cgi/tech/1331902463/
Part19 ttp://toro.2ch.net/test/read.cgi/tech/1340760070/
0666デフォルトの名無しさん2012/12/14(金) 15:22:59.66
>>664
釣りっぽいが、併行してやるのがお薦め。

>>665 はもうちょっと練ろうな。
進化上のトライ&エラーは、全員が何時までも繰り返しやるべき事じゃない。
俺は先人の成果を感謝しながら使わせて貰うけど、それが嫌らしいから、全部独力でやってくれ。
0667デフォルトの名無しさん2012/12/14(金) 15:29:04.45
トライアル&エラー
0668デフォルトの名無しさん2012/12/14(金) 15:35:20.57
そんなに向かっ腹を立てるほどの釣りかなあ。
0669デフォルトの名無しさん2012/12/14(金) 16:50:33.05
HDBC.PostgreSQL の withPostgreSQL' にはドキュメントがありません

これは正格版ということでしょうか?
0670デフォルトの名無しさん2012/12/14(金) 17:51:50.24
たぶんsrc見るとすぐに分かる
0671デフォルトの名無しさん2012/12/14(金) 18:04:45.77
トランザクションの連鎖モードと非連鎖モードの違いやね
'付きはBEGIN無しの非連鎖モード
0672デフォルトの名無しさん2012/12/14(金) 21:21:59.74
>>671
あり^^
0673デフォルトの名無しさん2012/12/17(月) 23:58:29.41
関数型言語はHaskellが初めてなんだけど、関数型言語で真っ先に理解すべき概念て何?
言語の経験はCだけでどこからかじったらいいかわからないっす
スレ違いならゴメン
0674デフォルトの名無しさん2012/12/18(火) 00:16:42.49
代入できないよ
0675デフォルトの名無しさん2012/12/18(火) 00:25:43.35
>>673
ビビらせて喜んでるのは、ニワカだから無視していい。
ttp://www.sampou.org/haskell/tutorial-j/index.html
を読んでみて。
0676デフォルトの名無しさん2012/12/18(火) 00:38:44.50
複雑なデータ構造があって
それがリストに並んでるとします
deepseqすると全部のリストを洗って全部の要素をNF化するんですよね?

リストは全部タッチ(e:?で止めないでe1:e2:e3:…en:[]まで)して欲しいけどけど
個々の要素をNF化する必要は無いときはどうしますか?
0677デフォルトの名無しさん2012/12/18(火) 01:36:59.76
>>675
あんがと
Cつっても組み込み実装の用途だったから関数言語のアカデミックな思考とは今まであんまり縁がなかったなあ・・
関数言語使えるようになったらシステム制御とかすごい効率的に書けそう
0678デフォルトの名無しさん2012/12/18(火) 02:31:09.17
fprintf文が使えなくてイライラする
C言語の入出力は実は悪くないとあらためて実感できる
0679デフォルトの名無しさん2012/12/18(火) 03:24:25.21
いやあれは悪いだろ
0680デフォルトの名無しさん2012/12/18(火) 08:10:21.22
>>678
sprintfがあれば十分だろ
0681デフォルトの名無しさん2012/12/18(火) 10:31:21.64
>>677
こんなのもあるよ。
Haskellで作る超コンパクト音声認識システム:Husky
ttp://www.furui.cs.titech.ac.jp/~shinot/husky/
0682デフォルトの名無しさん2012/12/18(火) 16:04:02.18
>>681
Sugeeeeeee!と思ってライブラリアーカイブ漁ったらコマンドライン簡易計算機が出てきたでござるの巻
0683デフォルトの名無しさん2012/12/18(火) 18:54:45.46
>>676
import Control.Seq
r = seqList r0
でどうだろうか
0684デフォルトの名無しさん2012/12/18(火) 19:08:30.54
returnが不適切だというなら、じゃあ何が良かったんだよ?

monadize
0685デフォルトの名無しさん2012/12/18(火) 19:26:12.84
unitやetaあたりだけどdo記法内で手続き型っぽく書く事を主眼に入れたとしたらreturnが適切なんじゃね?
っていう議論が大昔にあった筈だからその辺の歴史も知った上で考えたいのだけどそんな資料ありませんかね
0686デフォルトの名無しさん2012/12/18(火) 22:30:23.06
return の代わりに eta
join の代わりに  hinin

ってのがいいと思う
0687デフォルトの名無しさん2012/12/19(水) 20:44:44.19
bindが記号?(>>=)があるのに対して
returnにはないのは何故ですか?
0688デフォルトの名無しさん2012/12/19(水) 20:56:29.95
>>687
記号だとプログラムが読みにくいから
0689デフォルトの名無しさん2012/12/19(水) 20:59:39.61
メリットがないんじゃないか
そもそも単項演算子なんて(-)ぐらいのもの
命令型言語とのアナロジーも考えればreturnでいいでしょう
0690デフォルトの名無しさん2012/12/19(水) 20:59:56.08
記号が読みにくいのは同感なんですが
じゃあ何故bindは>>=なのかが疑問なんです
統一感がないっていうか・・
0691デフォルトの名無しさん2012/12/19(水) 21:01:43.29
>>690
bindな>>=なのはプログラムが読みやすいから
0692デフォルトの名無しさん2012/12/19(水) 21:03:25.98
>>690
統一感がないという理由なら、fail にも記号が必要になる

あるいは、(>>=) と (>>) も演算子ではなく関数名を定義するか
0693デフォルトの名無しさん2012/12/19(水) 21:03:34.64
m >>= k >>= l
m `bind` k `bind` l
では前者のほうが読みやすいでしょう
中置記法は優先度も決められないしね
0694デフォルトの名無しさん2012/12/19(水) 21:12:23.99
なんかこう包みこんだり持ち上げたりするようなイメージの
ぐっとくる記号があったら採用されてたかもしれんな
0695デフォルトの名無しさん2012/12/19(水) 21:16:37.02
>>693
> 中置記法は優先度も決められないしね

関数 f も infixr 5 `f` で中置記法としての優先度や結合の向きを定義できる
0696デフォルトの名無しさん2012/12/19(水) 21:17:56.38
>>695
15へぇ
0697デフォルトの名無しさん2012/12/19(水) 21:18:25.23
なるほど。bindはイメージがしやすい記号が合ったけど
returnにはそれがなかった。と言う事ですか
0698デフォルトの名無しさん2012/12/19(水) 21:20:03.95
記号は二項演算子のように挟まれるか、括弧のように挟むために使う
0699デフォルトの名無しさん2012/12/20(木) 00:15:39.97
return じゃなくて inject にすべきだったのではなかろうか
0700デフォルトの名無しさん2012/12/20(木) 10:36:24.58
>>699
モナド=コンテナ 的な発想だとそうなるんだけどね。
Maybe はコンテナか?とか
0701デフォルトの名無しさん2012/12/20(木) 10:38:12.62
流石に今更returnをinjectに変えるのはなあ
0702デフォルトの名無しさん2012/12/20(木) 11:42:45.44
書きやすさで言えば inject = return とすればいいだけだから平和だ
争いは読むレベルで発生する
0703デフォルトの名無しさん2012/12/20(木) 11:53:27.05
そろそろコモナド入門誰か書いてよ
0704デフォルトの名無しさん2012/12/20(木) 12:17:42.00
コモナドって何に使うの?
0705デフォルトの名無しさん2012/12/20(木) 12:21:46.79
arrowがコモナドとか思ってるんじゃね?
ちなみにarrowはコモナドじゃねーぞ
0706デフォルトの名無しさん2012/12/20(木) 12:27:03.75
コモナドはarrowになれる
0707デフォルトの名無しさん2012/12/20(木) 12:45:59.17
「こどもでもわかるコモナド入門」
0708デフォルトの名無しさん2012/12/20(木) 13:14:51.42
co-monadとarrowは全く違う
0709デフォルトの名無しさん2012/12/20(木) 14:11:29.17
そんなの知ってるからコモナドの応用例出せ
0710デフォルトの名無しさん2012/12/20(木) 14:15:09.36
例: Coreader (a.k.a Env)
localの使えないReaderMonad
つまりゴミ
0711デフォルトの名無しさん2012/12/20(木) 15:07:04.74
Identityコモナド
0712デフォルトの名無しさん2012/12/20(木) 17:02:39.67
お前ら難しい概念は一杯知ってるのに実用できてないよね
0713デフォルトの名無しさん2012/12/20(木) 17:28:05.58
だから実用例出せって言ってる
0714デフォルトの名無しさん2012/12/20(木) 19:30:38.86
>>713
俺は全く分からんが、このじーさんがその手の実用を惜しみなく公開しているっぽい
http://conal.net/blog/
0715デフォルトの名無しさん2012/12/20(木) 22:54:32.75
分散並列処理フレームワークありませんか?
0716デフォルトの名無しさん2012/12/20(木) 23:20:37.62
>>715
どういう事ができる分散並列処理フレームワークが欲しいの?
0717デフォルトの名無しさん2012/12/20(木) 23:31:12.67
世界征服
0718デフォルトの名無しさん2012/12/20(木) 23:34:34.78
>>717
その程度で良いのなら自分で作れ
0719デフォルトの名無しさん2012/12/21(金) 04:52:06.99
哲学は結構です
Haskellの話をお願いします
0720デフォルトの名無しさん2012/12/21(金) 12:21:13.87
これからのHaskellはどうあるべきか
0721デフォルトの名無しさん2012/12/21(金) 12:46:25.70
兎に角実用例を増やす
必要なのは信頼と実績のみ
理論方面は証明支援系に任せましょう
0722デフォルトの名無しさん2012/12/21(金) 13:11:28.86
まとなIDEだな
emacsとかはもう嫌
0723デフォルトの名無しさん2012/12/21(金) 16:19:53.42
haskellはビジュアルプログラミングに向いてると思うね。
Yahoo! pipes的なの誰か作ってよ。
0724デフォルトの名無しさん2012/12/21(金) 16:41:55.99
ログ取ろうとする初心者が必ず陥るであろう罠
モナドで順序保証といえど遅延であるという事実
これが意図に反する挙動を招く事について解説するべきだ
0725デフォルトの名無しさん2012/12/21(金) 18:13:48.40
「やりたいこと」ではなく「できること」をプログラムしましょう
やりたいけどできない挙動はあっても、できるけどできない挙動というのはありえません
0726デフォルトの名無しさん2012/12/21(金) 19:15:07.14
>>723
Haskellのどの辺りがビジュアルプログラミングに向いてるのでしょうか。
0727デフォルトの名無しさん2012/12/22(土) 00:11:16.33
>>726
イベントドリブンの実装のしやすさ
0728デフォルトの名無しさん2012/12/22(土) 06:43:37.72
イベリコブタの調理のしやすさ
0729デフォルトの名無しさん2012/12/22(土) 14:29:59.23
>>728
プロシュートいいよね
0730デフォルトの名無しさん2012/12/27(木) 03:50:17.10
諸君、議論がお留守だよ
0731デフォルトの名無しさん2012/12/27(木) 16:16:16.13
結合リスト
data Tree a = Single a | App (Tree a) (Tree a)

を普通のリストに変換する関数

toList :: Tree a -> [a]
toList (Single a) = [a]
toList (App (Single a) xs) = a:toList xs
toList (App (App xs ys) zs) = toList $ App xs $ App ys zs

この関数の2つ目の式では呼び出しの度に要素数が減ってるけど
でも3つ目の式では要素数が減ってない
でも有限リスト与えた時にちゃんと止まる
じゃあ3つ目の式と2つ目の式でに共通の呼び出し毎に減っているものは何ですか?
整礎帰納法の例で探してもマージソートとか割り算ばっかりで木の平坦化とか全然出てきません
0732デフォルトの名無しさん2012/12/27(木) 16:31:39.00
>>731
単に止まることを証明したいという意味?
俺なら
1. どの操作でもAppが増えることはない
2. 左側の木の高さが1以上の場合は左側の木の高さが減る、0の場合はAppが減る
というあたりから攻める
との操作でも減るような上手い値を定義したいということなら分からん
0733デフォルトの名無しさん2012/12/27(木) 19:02:10.89
>>731
App xs ys が xs に減ってるじゃん
0734デフォルトの名無しさん2012/12/27(木) 19:17:07.39
えっ……
0735デフォルトの名無しさん2012/12/27(木) 20:17:19.95
参照的な構造(動的に変更される有向グラフ)を表すにはどうしたらいい?

グラフの形状は、環状構造とか、分断されてるとか、そういうのもあって仮定できないとして

addNode :: a -> Graph a -> (Graph a, Node a)
deleteNode :: Node a -> Graph a -> Graph a
getValue :: Node a -> Graph a -> a
putValue :: Node a -> a -> Graph a -> Graph a
connect :: Node a -> Node a -> Graph a -> Graph a
disconnect :: Node a -> Node a -> Graph a -> Graph a
connections :: Node a -> Graph a -> [Node a]

こういう関数を純粋に定義するにはどうしたらいい?
特に、ノードやエッジ、グラフを表す型はどういうものにすべき?
「純粋に」というのは、関数の引数や返り値にIOやSTの類が現れないということ unsafePerformIO みたいな「抜け穴」の使用はナシで
0736デフォルトの名無しさん2012/12/27(木) 20:33:11.53
>>375
君は、任意のグラフではなく、ツリー構造なら問題なく >>375(の様なもの)を実現できる?
もっと言うと、一列のリスト構造なら問題なく実現できる?

それなら実現できると言うのなら、グラフ構造だと何故できない?
グラフ構造とそれ以外の構造との >>375 を実現する上での本質的な違いは何?
0737デフォルトの名無しさん2012/12/27(木) 21:43:08.04
>>735
頂点、辺をそれぞれ整数で表わす
data Graph a = Graph
 { nodes :: IntMap (a, [Int]) -- [Int]はここから出る辺のリスト
 , edges :: IntMap (Int, Int) -- 出発頂点と行き先頂点
 , nextInt :: Int -- 次に頂点や辺を作ったときに割り当てる整数
 }
0738デフォルトの名無しさん2012/12/27(木) 22:04:12.36
問題の一つは、循環があると構造が再帰的にならないこと

data List a = List a (List a) | Nil
とか
data Tree a = Tree a [Tree a]
と定義するのと同じような感じで
data Node a = Node a [Node a]
と定義してしまうと、Eqのインスタンスにすることさえできない (有限なグラフに対しても(==)が停止しない可能性がある)

循環構造を考えないとしても、グラフには、リストの頭や木の根みたいな「どこからも参照されていない唯一の基準点」がない
仮に木構造の参照の向きを全部逆にしたような構造があったとき、その根が変更されたら、それをどうやって全てのノードに伝えたらいいのだろうか
唯一のエントリーポイントが存在するなら、そこから変更点までの、影響を受ける全てのノードを(陰にせよ陽にせよ)記憶しておけばいいけど、グラフだとそうはいかなくなってしまう
0739デフォルトの名無しさん2012/12/27(木) 22:56:29.51
>>738
>有限なグラフに対しても(==)が停止しない可能性がある

ん? 必ず停止する同値判定プログラムは書けるが、
複雑で面倒と言うことだよね?
(循環を検知できないわけがない)

>>737 の方法でも、同値判定をする必要があるのなら、
循環を検知する同じような仕組みが必要だぞ。
0740デフォルトの名無しさん2012/12/27(木) 23:19:51.93
data Node a = Node a [Node a]
というだけの構造でも循環は検知できるんでしょうか?

x = Node 0 [Node 1 [x]]
y = Node 0 [Node 1 [y]]

に対して
x == y
が停止してTrueを返す(==)って定義できるんでしょうか
0741デフォルトの名無しさん2012/12/27(木) 23:30:16.00
出そうと思えば(unsafeCoerce)
0742デフォルトの名無しさん2012/12/28(金) 06:07:19.07
>>735
単に隣接行列を持てばいいだけだと思うけど
0743デフォルトの名無しさん2012/12/28(金) 06:11:44.81
>>739
循環は検知できないだろ
たとえば[Int]を与えられたときに、それが
・普通の無限リストなのか
・単にやたらと長いリストなのか
・let a = 0:a in aのように作られた循環リストなのか
判別することはできない

>>738の構造ではグラフの頂点数を数えることすらできないし、
辺の追加や削除もできない
どうしても>>737みたいなグローバルなテーブルを持つを持つ必要がある
0744デフォルトの名無しさん2012/12/28(金) 06:39:32.04
>>740はノードが二個のグラフのつもりなんだろうけど、

x = Node 0 [Node 1 [x]]
z = Node 0 [Node 1 [Node 0 [Node 1 [z]]]]

この二つが全く同じデータになっちゃうんだからおかしいよね
最低でもノードの同一性判定は必要(ノードの持つ値が同一というのではなく)
0745デフォルトの名無しさん2012/12/28(金) 07:08:57.06
>>742
隣接行列を2次元配列で表現するとノードの追加や削除が非効率
また、辺が無いところが無駄になる

検索の効率は良いけどね
0746デフォルトの名無しさん2012/12/28(金) 07:14:42.62
>>744
今まで比較した全てのものを記録しておいて、
[x] と [Node 0 [Node 1 [z]] を比較すれば判定できると思うけど。

判定処理の中で随時別のグラフ表現にフォーマットし直しながら判定すれば、
非常に馬鹿で無駄で非効率で面倒で阿保だけど、不可能ではないような気がする。

ダメかな・・・
0747デフォルトの名無しさん2012/12/28(金) 07:26:54.43
>>746
いやできないって
xとzを定義した時の式が後から取り出せるわけじゃないんだぞ
0748デフォルトの名無しさん2012/12/28(金) 08:13:27.86
ポインタをモナッドでエミュレート出来ないんですか
0749デフォルトの名無しさん2012/12/28(金) 08:53:49.77
>>747
data Node a = Node a ID [Node a]

というように、各ノードを区別できる全体で一意のノードIDを持たせても無理?
0750デフォルトの名無しさん2012/12/29(土) 02:07:43.84
>>749

それだと同一性判定は可能といえば可能だけど
n > 1のn部グラフは表現できない
という問題がありそう。

一例を挙げれば、点が二つで辺が一つもないグラフと、点が二つで辺が一つだけのグラフをどうやって区別するの、ってこと。

なお、オレは>>747とは別人ね。
0751デフォルトの名無しさん2012/12/29(土) 09:51:22.04
>>750
Data Graph a = Graph [Node a]
data Node a = Node a ID [Node a]
07527512012/12/29(土) 09:53:16.93
>>750
すまん、>>751 は変だな

まぁ、こんな感じでリストを組んでおけばn部グラフも表現できるでしょ

検索処理とか面倒そうなんで、俺はやらんが
0753デフォルトの名無しさん2012/12/29(土) 10:28:35.98
なんかGC実装したときみたいに物凄く難しくなる気がするのだが
0754デフォルトの名無しさん2012/12/29(土) 10:50:10.35
いや、だから「同値判定は不可能」というのは違うよね
と言いたかっただけだ

実際にプログラムするなら >>737 の方法がシンプルでいいと思うぞ
0755デフォルトの名無しさん2012/12/29(土) 11:00:02.95
むしろ、同値判定は簡単だけど、独立した循環参照の検出と抽象構造の同一視が難しい気がする
0756デフォルトの名無しさん2012/12/29(土) 11:07:38.80
programming in haskellとかいうpdfを読んでみたけど
稚拙な英語で書いてあったから日本人でもよく分かると思ったよ。
とりあえず7章までは問題なく読めたからオススメしておく。
0757デフォルトの名無しさん2012/12/29(土) 11:09:26.96
稚拙ってけなしてるようにしか聞こえんなw
0758デフォルトの名無しさん2012/12/29(土) 11:35:07.48
平易と言え
0759デフォルトの名無しさん2012/12/29(土) 11:42:31.40
稚拙 -> Unskilful
平易 -> Plain
07607312012/12/29(土) 13:09:04.38
渡された木の頂点から各要素への左向きの辺の数の総和を見ればいけました
総和なのである左向きの要素の階層が減った場合でも要素数が減ってもいけるわけですね
直近のグラフに関する話題が良いヒントになりました

numLEdge' :: Int -> Tree a -> Int
numLEdge' n (Single _) = n
numLEdge' n (App x y) = numLEdge (succ n) x + numLEdge n y

numLEdge = numLEdge' 0
0761デフォルトの名無しさん2012/12/30(日) 01:40:11.45
Integer型で何桁でも整数取り扱えるじゃん?
小数点何位でも取り扱える小数型ってないん?
0762デフォルトの名無しさん2012/12/30(日) 08:27:53.97
>>761
Data.Ratio
0763デフォルトの名無しさん2012/12/31(月) 18:50:13.91
あれがそうなのか
0764デフォルトの名無しさん2012/12/31(月) 22:28:49.72
上に出てきたグラフ構造もそうだけど
データ構造内の異なる複数の個所から
あるデータを参照するにはどうすればいい?
やっぱり整数値をポインタに見立ててIntMapでごにょごにょするしかない?
0765デフォルトの名無しさん2012/12/31(月) 22:29:59.12
emacsでhaskellのソースコードを書いているときに、C-c C-l と入力すると
ghciが起動してそのソースコードを読み込んでくれるのですが、
その方法で起動したghciの中で補完機能(termの中でTabを押すことで使えるやつ)
が使えるようにするにはどんな設定/elispを使ったらいいんでしょうか。
■ このスレッドは過去ログ倉庫に格納されています