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

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
2デフォルトの名無しさん:2010/10/10(日) 19:37:23
           __
        , ‐' ´   ``‐、             / ̄:三}
.     /,. -─‐- 、.   ヽ        /   ,.=j
 _,.:_'______ヽ、 .!       ./   _,ノ
  `‐、{ へ  '゙⌒ `!~ヽ. !     /{.  /
    `! し゚  ( ゚j `v‐冫   , '::::::::ヽ、/     そんなことよりDelphiしようぜ!
.    {.l   '⌒      ゙ 6',!   / :::::::::::::::/ __
.     〈  < ´ ̄,フ  .ノー'_ , ‐'´::::::::::::::;/ (_ノ)‐-、
.      ヽ.、 ` ‐", ‐´‐:ラ ':::::::::::::::: ;∠.   ヽ_}  ゙ヽ
        ,.r` "´  /:::::::::::::::::::ィ´  `ゝ  !、  /
     /       / :::::::::::::::: ; '´   /´\ /   r'\
.     i      ! ::::::::::::::/ 墨 | .!::::::::/ヽ、.._!ヽ. ヽ、
     {      {:::::::::::;:イ /   ‖i:::::::/:::::::::::::/  \
.      ヽ       ヽ,.ァ‐'´ /ヽ 二 ,/`ヽ、::::::::: /
3デフォルトの名無しさん: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/
4デフォルトの名無しさん: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
5デフォルトの名無しさん:2010/10/10(日) 19:43:18
Haskell API search Engine
ttp://www.haskell.org/hoogle/
6デフォルトの名無しさん:2010/10/10(日) 19:45:44
>>1
7デフォルトの名無しさん:2010/10/10(日) 19:46:09
8デフォルトの名無しさん:2010/10/10(日) 20:06:04
           __
        , ‐' ´   ``‐、             / ̄:三}
.     /,. -─‐- 、.   ヽ        /   ,.=j
 _,.:_'______ヽ、 .!       ./   _,ノ
  `‐、{ へ  '゙⌒ `!~ヽ. !     /{.  /
    `! し゚  ( ゚j `v‐冫   , '::::::::ヽ、/     そんなことよりC#しようぜ!
.    {.l   '⌒      ゙ 6',!   / :::::::::::::::/ __
.     〈  < ´ ̄,フ  .ノー'_ , ‐'´::::::::::::::;/ (_ノ)‐-、
.      ヽ.、 ` ‐", ‐´‐:ラ ':::::::::::::::: ;∠.   ヽ_}  ゙ヽ
        ,.r` "´  /:::::::::::::::::::ィ´  `ゝ  !、  /
     /       / :::::::::::::::: ; '´   /´\ /   r'\
.     i      ! ::::::::::::::/ 墨 | .!::::::::/ヽ、.._!ヽ. ヽ、
     {      {:::::::::::;:イ /   ‖i:::::::/:::::::::::::/  \
.      ヽ       ヽ,.ァ‐'´ /ヽ 二 ,/`ヽ、::::::::: /
9デフォルトの名無しさん:2010/10/12(火) 17:54:16
fmapの代わりに<$>を覚えたよ!(o^∀^o)
10デフォルトの名無しさん:2010/10/12(火) 20:16:24
<$> くらいはいいけど、算術以外の中置演算子はほどほどにな
調子こくと自分でも何やってるのか分かんなくなるから

俺は、最近は関数を中置で使うことが多くなってる
こっちも、調子こくとエディタの編集画面かうざくなるが
a `fmap` b
11デフォルトの名無しさん:2010/10/12(火) 20:27:19
むしろshe(プリプロセッサ)を使って
f <$> a <*> bを(| f a b |)と書くとか

ただしエラーメッセージが解読不能になる諸刃の刃
12デフォルトの名無しさん:2010/10/13(水) 01:19:59
>>11

そんなのあるんだ。
>>9じゃないけど、勉強になった。
サンクス。
13デフォルトの名無しさん:2010/10/15(金) 09:00:27
公式のLLVMの切れたリンク、なんなの?
14デフォルトの名無しさん:2010/10/15(金) 09:08:21
なんなの、って、メンテ忘れじゃない?
15Perl忍者 ◆M5ZWRnXOj6 :2010/10/16(土) 16:44:43
ほんとこのクソスレのびねえな

終了〜
16デフォルトの名無しさん:2010/10/16(土) 21:59:42
vip de yaruo.
17デフォルトの名無しさん:2010/10/17(日) 12:52:46
Pearls of Functional Algorithm Designやっと届いたぜ。wktkしながら頁をめくるか
18デフォルトの名無しさん:2010/10/18(月) 12:46:53
>>17
俺もちょっと前から少しずつ読んでる
15ページ目でいきなり躓いてるがな
19デフォルトの名無しさん:2010/10/18(月) 12:52:49
FRP の Arrow による実装に興味がある者には下記の論文を勧める

Plugging a Space Leak with an Arrow

Arrow 以前の実装で起きてたスペースリークを
Arrow で解決した話が詳細に書かれている
20まつもとひろゆき:2010/10/18(月) 17:07:35
こんなゴミスレいらん。
21デフォルトの名無しさん:2010/10/18(月) 17:54:48
>>20
IP抜きました
本人確認
22デフォルトの名無しさん:2010/10/18(月) 18:10:33
>>21 つまらないよ
23デフォルトの名無しさん:2010/10/18(月) 20:16:56
>>20-22自作自演
24デフォルトの名無しさん:2010/10/18(月) 21:13:33
>>20-23自作自演な気がする。。。 
25Perl忍者 ◆M5ZWRnXOj6 :2010/10/18(月) 23:56:01
20~24はHaskell板にふさわしくない書き込みですね

20〜24だけをみると
まるでHaskell板の面影すらありません

そう思いますよね???
26デフォルトの名無しさん:2010/10/19(火) 00:10:48
itパスポートは どうなったよ??
27Perl忍者 ◆M5ZWRnXOj6 :2010/10/19(火) 09:33:28
JPA公認企業の20台後半〜50台くらいのやつが消滅したらPerlerの大半が消える
28Perl忍者 ◆M5ZWRnXOj6 :2010/10/19(火) 09:38:45
Perlerってモダンの書き方しってるやつな

くそみてええなのは含まれません!
29デフォルトの名無しさん:2010/10/19(火) 10:06:10
>>28
モダンってどんな書き方?
30デフォルトの名無しさん:2010/10/19(火) 10:11:39
クソコテにかまうな
31デフォルトの名無しさん:2010/10/19(火) 10:12:30
まさに糞コテだよな。
有益な情報を一切ださない奴。
32デフォルトの名無しさん:2010/10/20(水) 10:44:14
みんな喧嘩は辞めて!><
33Perl忍者 ◆M5ZWRnXOj6 :2010/10/20(水) 11:31:10
FPS勝負しないか?
haskellじゃねーぞ
プログラマと1回 FPSをやってみたいんだけど
お前らができるFPSをいってくれ 俺はそれをダウンロードしてスタンバイするので
34デフォルトの名無しさん:2010/10/20(水) 12:01:13
言っておくが俺はチートするぜ
35Perl忍者 ◆M5ZWRnXOj6 :2010/10/20(水) 12:11:30
チーとでもなんでもこい
早くFPSのゲーム名いえよ
36デフォルトの名無しさん:2010/10/20(水) 12:18:45
DOOM
37Perl忍者 ◆M5ZWRnXOj6 :2010/10/20(水) 12:24:26
doom知ってんぞ体験版?
はやくURLはれ
38デフォルトの名無しさん:2010/10/20(水) 12:30:49
馬鹿はテンション高いな
39デフォルトの名無しさん:2010/10/20(水) 18:59:53
FPSあげ
40デフォルトの名無しさん:2010/10/20(水) 20:34:01
FPSあげ あげ
41デフォルトの名無しさん:2010/10/20(水) 20:50:23
むしろFRP希望。
42デフォルトの名無しさん:2010/10/20(水) 21:37:09
FRPを使ったゲームを誰が最速で書けるか勝負しようぜ!
43デフォルトの名無しさん:2010/10/20(水) 22:52:52
44Perl忍者 ◆M5ZWRnXOj6 :2010/10/20(水) 23:00:21
>>43
俺の偽だろ!!!
ガッチムッチの思い切り!ガッチムチ羽ばたいて!飛んで飛んでアソコへ!レディゴーレディゴー!レディゴー!(ガチガチ! oh〜ガチムチー!!!
45デフォルトの名無しさん:2010/10/20(水) 23:15:35
ところで、Perl忍者は Haskell は使えるのか?
使えるのなら、小粒でいいから何かテクニックでも紹介していけ

使えないのなら、邪魔だから騒がしくするな
46デフォルトの名無しさん:2010/10/21(木) 00:00:45
ちょっと前にHaskell勉強しはじめた者ですが、
小難しいモナドでつまづいてます。
皆さん何を勉強してモナドが何者か納得できましたか?
とりあえずWadlerの論文みつけたので、
これ読めばなんかつかめるかなとは期待してるんですが、英文だし効率悪い。
47デフォルトの名無しさん:2010/10/21(木) 00:12:11
>>46
Haskellを使うためにモナドを勉強するならこれで十分だと思います。

世界で一番か二番くらいにやさしい「モナド入門」
http://d.hatena.ne.jp/m-hiyama/20060419/1145432492
48デフォルトの名無しさん:2010/10/21(木) 00:27:28
おお、さっそくありがとうございます。
おすすめのページじっくり読んでみます。
まずはお礼まで。
49デフォルトの名無しさん:2010/10/21(木) 07:56:25
>>46
[モナド] を理解することと、
[モナドで副作用を閉じ込める仕組み(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. がどのようなものかを知れば、モナドが見えてくるよ。
50Perl忍者 ◆M5ZWRnXOj6 :2010/10/21(木) 08:08:02
本かわせんじゃねえよ作者
51Perl忍者 ◆M5ZWRnXOj6 :2010/10/21(木) 08:11:15
本買わせるんじゃねえよ著者
52デフォルトの名無しさん:2010/10/21(木) 09:07:49
モナドの目的は、本来の目的を情報隠蔽することだと思います。
問題は、隠蔽するやり方が何通りもあったために、かえって偶有的属性が増えてしまった
ということだと思います。
5349:2010/10/21(木) 09:09:35
>>49
すまん、[モナド] の 2. は違うな
バインドはモナドどうしの演算じゃなかった
[モナド] と [そのモナドで包んでるものに対する関数] との演算だったよ

あと、[有理数] の 1. は別に整数でなくてもいい
複素数でもその他でもいいが、整数が一番簡単だったから
54デフォルトの名無しさん:2010/10/21(木) 12:54:25
>>52
>モナドの目的は、本来の目的を情報隠蔽することだと思います。

どういうこと?

たとえば、ある代数データ型をある目的で使いたいが、その目的を隠したい、
そういう時にその代数データ型をモナドにすることを考えてみるといい、
ということですか?
55デフォルトの名無しさん:2010/10/21(木) 13:01:17
>>52はつまらない冗談か、もしくは気が狂っているので無視していいよ
56デフォルトの名無しさん:2010/10/21(木) 15:20:32
確かに、本質を見るためには、つまらないものを隠せばよいと思います。
しかし、つまらないという基準はただの主観だと思います。
57デフォルトの名無しさん:2010/10/21(木) 15:34:43
この世は主観で出来ているのですよ。
あなたはこの世界を五感と知性によって認識しているでしょう。
58Perl忍者 ◆M5ZWRnXOj6 :2010/10/21(木) 23:44:59
お笑いブームの影響で
おもしろいの基準あがってるからしょうがねえんだよかす
59デフォルトの名無しさん:2010/10/21(木) 23:47:18
>49
オブジェクト(≒集合の元)を「モナド」と呼んでる段階で眉に唾をつけたくなる.
60Perl忍者 ◆M5ZWRnXOj6 :2010/10/21(木) 23:49:01
>>57
てめえ
うちはイタチの真似してんだろこら

「人は己の知識や認識に頼り縛られ生きている…それを現実と呼んでな。しかし現実とはあいまいなものだ。それは幻かもしれない

お前もNARUTO好きか?
61デフォルトの名無しさん:2010/10/22(金) 03:20:06
>>60
仏教思想で答えただけなんだがな・・・
仏教では、世界とは八識(五感+意識+末那識+阿羅耶識)で物事を認識することによる主観の産物だっていうのが定説。
6249:2010/10/22(金) 07:32:55
>>59
俺自身も書いた後でこの捉え方はどうかとちょっと疑問だった。
(いろいろ突っ込みどころはあるだろうし)

が、少なくともオブジェクト(≒集合の元)を「モナド」と呼んだつもりはないのだが。
[モナド] の 3. のところがマズったか。

小学校や中学校、高校で「割り算とは何ものか?」という本質は学ばず、
「割り算は**という演算だよ」とだけ教えられ、さっさと学習を進めたはず。
微分、積分、内積なども同じだと思う。

ちょっと前に Haskell 勉強しはじめた者も Haskell に関しては同じ立場だから、
「モナドは**という演算ができて、##という性質があるよ」
の**と##をまず調べたらどうかと言いたかった。
それはモナドの理解のほんの一部だけだけど、
それだけでも Haskell の学習を進めるのには十分だから。
63Perl忍者 ◆M5ZWRnXOj6 :2010/10/22(金) 07:38:55
仏教
64デフォルトの名無しさん:2010/10/22(金) 08:09:18
>62
「1を return でくるめば(return 1)モナドになる」
「(Just x) と (Left y) (モナド同士)に特別な演算ができる」
って変でしょ?
(return 1)の属する型(IO Int なり Maybe Int なり)と演算 >>=, >>, return の組がモナド.

あなたの書き方だといつでもモナドの元同士に対する演算が定義されていると読めて,
データを型で区別してプログラムの質を高める,という考え方と真っ向から対立し
読者に混乱を引き起こす.
65デフォルトの名無しさん:2010/10/22(金) 11:05:26
仏教≒マトリックス
これならここの住人にも理解できるんじゃないか。
66デフォルトの名無しさん:2010/10/22(金) 11:57:35
モナドの一つの側面は
一度その型で始めたら途中変更は利きませんからね
って事ですかね
67デフォルトの名無しさん:2010/10/22(金) 12:37:22
ですかね
と問われたら違うというほかない
6849:2010/10/22(金) 12:39:49
>>64
演算はモナドどうしではなかったと >>53 で訂正したぞ
(>>=、>> の右辺はモナドじゃないから)


>>66
できるよ
[String] から [Int] に変更できるでしょ
69デフォルトの名無しさん:2010/10/22(金) 12:40:30
そうですか、違うんですか(´・ω・`)
70デフォルトの名無しさん:2010/10/22(金) 12:43:54
初心者が具体例なしに理屈だけ聞いて分からないから困ってんのに
変な理屈だけ増やしてどうすんだろな

モナドを使わずに書いた場合と比べてみれば
少しはありがたみが分かる
71デフォルトの名無しさん:2010/10/22(金) 12:51:54
>>70
>初心者が具体例なしに理屈だけ聞いて分からないから困ってんのに

そんなこと一言も聞いてないが
逆に例ばかりで理屈が分からないとも聞いてないけどね

自分が知りたいんだと素直に言ったら?
72デフォルトの名無しさん:2010/10/22(金) 13:02:52
世界は人の主観の産物なのだから本質は「無」なのだ、というわけ。
73デフォルトの名無しさん:2010/10/22(金) 13:38:55
いつからこのスレはこんな電波っぽくなったんですか?(´・ω・`)
74デフォルトの名無しさん:2010/10/22(金) 13:48:10
仏教を電波扱いするな。
お釈迦さんバカにすんあ
75デフォルトの名無しさん:2010/10/22(金) 14:46:43
猿が増えたから減らします
76デフォルトの名無しさん:2010/10/22(金) 17:21:28
電波ぽいって主観じゃん
77デフォルトの名無しさん:2010/10/22(金) 19:53:05
とりあえず主観は悪くないとしても
他人の主観に便乗するやつはゴミ
78デフォルトの名無しさん:2010/10/22(金) 20:10:37
>>77
という主観ですね
79デフォルトの名無しさん:2010/10/22(金) 20:27:57
スレの住人が総取っかえになったみたいだな。
80デフォルトの名無しさん:2010/10/22(金) 20:32:17
haskellは仏教に似ている
81デフォルトの名無しさん:2010/10/22(金) 20:40:20
ヘイ! ジョージ! 今日も情事に励んでるかい? HAHAHA
82デフォルトの名無しさん:2010/10/22(金) 20:53:23
>>66
そんな側面はありません
83デフォルトの名無しさん:2010/10/22(金) 21:28:41
その話題はもう完了してる

今ほっとな話題は仏教だよ
84Perl忍者 ◆M5ZWRnXOj6 :2010/10/22(金) 23:22:49
うけるwwwwwwww
一瞬ここのスレみたら

仏教スレになってた
テラワロスwwwww
85デフォルトの名無しさん:2010/10/23(土) 01:13:28
86デフォルトの名無しさん:2010/10/23(土) 09:13:37
バイアスがひどいな。政治の道具にされ始めとる。
87デフォルトの名無しさん:2010/10/24(日) 18:18:17
荒らしに対抗できるのは荒らし
Perl忍者!頼んだぞ!
88デフォルトの名無しさん:2010/10/24(日) 18:56:06
釈迦(=仏陀=目覚めた人)はむしろ幽霊とか超常現象とかオカルトを批判していた側の人間なんだがなw
紀元前500年のインドはオカルト宗教であるバラモン教が力を持っていたが、
そのアンチテーゼとして釈迦の教えをまとめたのが仏教(上座部仏教)だ。
神に祈れば天国に行ける?バカをいうなw
仏陀は弟子にこういった、
小石を池に投げ込んで、浮かんでこい、浮かんでこい、と念じれば小石は浮かんでくるのか?
いや、浮かんできはしない。
念仏や祈祷や呪文を唱えたところで何も変わらんのだ。
そのくだらん映画を今すぐ取りやめろ。
89デフォルトの名無しさん:2010/10/24(日) 19:02:31
今の日本で普及しているゴミのような仏教は釈迦が死んだ700年後の後世に作られた大乗仏教に由来する。
この大乗仏教というやつは仏陀の教えを経典主義的に極端な形で屁理屈をこね回して作られたオカルト要素たっぷりのゴミ宗教だ。
そう、どんな素晴らしい教えでも凡人にかき回されるとゴミに変貌するわけだ。
Haskellだって、凡人が大量に使うようになると当初の理想なんて失って優柔不断な言語になるに決まっている。
だからperl忍者とかいうザコはどうしてもHaskell触りたいなら博士号取ってからにしろ。
90デフォルトの名無しさん:2010/10/24(日) 19:27:54
シッタルダの考えやHaskellの当初の理想なんってどうでもいいんだよ。
世間が求めているのは便利なものだ。
大乗仏教は人々に支持された。
Haskellは?
91デフォルトの名無しさん:2010/10/24(日) 19:29:25
F#でも使ってろ、が答えだと思う
92デフォルトの名無しさん:2010/10/24(日) 19:52:17
もしかして、CommonLispの方ですか。
93デフォルトの名無しさん:2010/10/24(日) 20:33:13
>>90
少なくとも嫌ってる人は少ないだろうな
大半は「好き」「はぁ?何それ」 のどちらかだろ
94デフォルトの名無しさん:2010/10/24(日) 21:37:37
儲はどこもキモイな〜
95デフォルトの名無しさん:2010/10/25(月) 06:40:22
具体的なことは何も言えないわけですねわかります
96デフォルトの名無しさん:2010/10/25(月) 12:13:28
10スレ前ぐらいで虐められた奴がまだ粘着しているって感じやね
97(信は力なり)Perl忍者 ◆M5ZWRnXOj6 :2010/10/25(月) 23:27:04
>>89
最後の行にPerl忍者とかかかれてもきずかないんですが

死ねよハゲ
98デフォルトの名無しさん:2010/10/25(月) 23:59:22
Arrow がなぜ生まれたのかを知りたい人たちに
John Hughes が著わした次の論文を紹介する。

Generalising Monads to Arrow

モナドの利点も簡潔にまとめてあるから、
モナドって何の役に立つんだ? という人にも参考になる。
99デフォルトの名無しさん:2010/10/26(火) 00:01:42
>>98
論文のタイトルが間違ってた。
細かいことだが著者に失礼なので訂正させてほしい。

Generalising Monads to Arrows
100デフォルトの名無しさん:2010/10/26(火) 13:39:10
IOモナドのような副作用系のモナドは、

1. 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モナドは量子ピタゴラススイッチなのだと理解できる日が来よう。
101デフォルトの名無しさん:2010/10/26(火) 18:15:32
>>100
>Maybeモナドはその劣化版

何となくだけど、ちょっとだけ引っかかる。

Monad クラスのインスタンスは全て等しく優劣無くモナドなんじゃないの?
何の視点で優劣を比べた結果 Maybeモナド が List モナドに劣ると考えたの?
102デフォルトの名無しさん:2010/10/26(火) 19:37:57
議論の本質ではないが、 Monad クラスのインスタンスがモナドとは限らないことには注意されたい。
もちろん、処理系が提供しているものに関しては整合性がとれるように設計されているはずだが。
103デフォルトの名無しさん:2010/10/26(火) 20:11:35
>>101
僕の誤解でなければ、[a]の値をaを0個か1個持つものだけに制限すると、
理論的(代数的)にはMaybe aとまったく同じもので、
それはMonadoクラスとしての働きもまったく同じはず。
104デフォルトの名無しさん:2010/10/26(火) 20:14:47
Monadoとか書いちゃった。oが多い。
サーセン。
105デフォルトの名無しさん:2010/10/26(火) 20:18:58
Maybeをモナドとして使う時はリストで完全に代用できるってことだな
Data.Maybe.maybeToListを使うと、Maybeの値をリストに変換でき、さらにこの変換がMonadインスタンスと整合する
整合するというのは以下の二つの法則が成り立つこと(なんか圏論の臭いがする)

maybeToList (return x) = return x
maybeToList (x >>= f) = maybeToList x >>= maybeToList . f
106デフォルトの名無しさん:2010/10/26(火) 21:17:22
>>103
なるほど、数学的には リストモナドは Maybe モナドを含んでいること、
その観点で Maybe モナドはリストモナドの劣化版だと言ったのは理解した
同意する

ただ、ちょっと確認しておきたい

数学的には同じでも、実際問題としてプログラムソースの中で Maybe a を使ってた所を全て
劣化版を完全版にしようとして要素が0個か1個の [a] で置き換えたらまずいよな?

ソースを保守しにくくなるよな?

そういう観点では、リストと Maybe は優劣を比べるものではなく、
むしろ全く別の役割のものだよな?
107デフォルトの名無しさん:2010/10/26(火) 21:19:22
>>106

すまん、>>106 の後半は >>105 に対してだ
108デフォルトの名無しさん:2010/10/26(火) 21:33:09
なるほど、[]=Nothing/[a]=Justか
横レスだけど、MaybeをListに置き換えると、
要素は0個か1個、という制約が抜け落ちてしまうから
置き換えることは出来るにしても、設計的には酷くなるからやめた方がいい
誤解に対しては、「劣化版」じゃなくて「特殊化版」って語を使えば良かっただけの話じゃないかな
109デフォルトの名無しさん:2010/10/26(火) 21:52:11
そのままでも使えるものに余計な装飾を施すことを劣化と言うなら、
newtypeなんか劣化の極みになるんじゃねいの
110デフォルトの名無しさん:2010/10/26(火) 22:05:48
>>107
「モナドとして、returnと(>>=)で操作する限りにおいては」リストを不自由にしたものに過ぎないと言えるけど、
値を取り出すことやその他の操作を考えれば劣化じゃないし、もちろんコーディング上の役割は違う
111100, 103:2010/10/27(水) 00:38:57
「劣化版」という言い方がよくありませんでした。ごめんなさい。

>>100 で言いたかったことは…
リストモナドの働きを理解すればその特殊化版であるMaybeモナドの働きも理解できるよ、
それと、IOモナドはStateモナドで理解できるから(Rreaderモナドなども)、
ひとまずStateモナドとMaybeモナドを理解すれば十分に視野が開けるよ、
ということです。

もちろん、何かを理解するための試行錯誤の上ではなく、
実用のコード上で、一般にMaybe aをList aに置き換えてしまうのは危険です。
112デフォルトの名無しさん:2010/10/29(金) 12:38:17
ここまでの議論を纏めます

・Maybeモナドは、Listモナドの要素数を0か1に制限した
 特殊な例であるという見方ができる

・Monadクラスのインスタンスがモナドであるとは限らない

・Perl忍者は電波である
113デフォルトの名無しさん:2010/10/30(土) 11:37:27
・Maybeは、Listに置き換えると危険である

・「コンパイルできたら安全」とは限らない
ここからの議論を期待します
114デフォルトの名無しさん:2010/10/30(土) 12:27:41
Haskellはオブジェクト指向ができますか?
115デフォルトの名無しさん:2010/10/30(土) 12:32:25
専用のサポートはないけどできる
カプセル化と多態はそのための機能がある。実装の継承の仕組みはない
メッセージ渡しはちょっと無理があるかも
116デフォルトの名無しさん:2010/10/30(土) 13:05:53
data Acceptor a b c = Acceptor (Visitor a b c -> c)
data 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
117デフォルトの名無しさん:2010/10/30(土) 13:13:26
Haskellでオブジェクト指向でプログラミングしないでください。
118デフォルトの名無しさん:2010/10/30(土) 13:53:46
それは何故ですか?(´・ω・`)
119デフォルトの名無しさん:2010/10/30(土) 14:45:04
QuickCheck の orderedList 関数は、説明には
与えられた長さの順序リスト生成器を生成するようなことが書かれていますが、
vector 関数のような引数は無いですよね。

どうやって長さを指定するのでしょうか。
resize 関数を作用させるしかないですか?
120デフォルトの名無しさん:2010/10/31(日) 18:46:37
オブジェクト指向は目的ではなく手段だから
121デフォルトの名無しさん:2010/10/31(日) 19:03:15
>>119
orderedListの定義はsort `fmap` arbitraryだからのぅ
fmap sort . vectorで代用すりゃいいんとちゃうか?
122デフォルトの名無しさん:2010/10/31(日) 19:38:08
関数型言語とオブジェクト志向って直交する概念だよね?
123デフォルトの名無しさん:2010/10/31(日) 21:03:22
>>121
なんか解説と違ってていまいち納得いかないが、
実用上はそれで問題ないような気がしてきた

ありがと
124デフォルトの名無しさん:2010/10/31(日) 23:13:45
>>122
同じ名前で異なるメソッドが呼ばれると嫌がられる気がする
高階関数は良いが、関数のタプルとか関数のリストとかはだめっぽい
125デフォルトの名無しさん:2010/10/31(日) 23:27:13
なにその偏見
126デフォルトの名無しさん:2010/10/31(日) 23:39:36
>>124
ちょっとまった。 Haskell でもオーバーロードがあるだろ。
127デフォルトの名無しさん:2010/11/01(月) 00:46:36
>>126
あるね
オーバーロードも嫌がられる場合がある
例えば、MaybeなのかListなのかはっきりしろ、みたいな
128デフォルトの名無しさん:2010/11/01(月) 18:42:33
諸君、ようやく議論を始めたようだね
129デフォルトの名無しさん: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) と書かれていて、
型変数が書かれていないといった旨のエラーだと思います。

このようーな型クラスは作れるのでしょうか。
作れるのなら、どのような方法で作れるでしょうか。
130デフォルトの名無しさん:2010/11/01(月) 20:05:05
>>129
これでは駄目?
class Monad m where
  return :: a -> m a
131130:2010/11/01(月) 20:10:07
ごめん勘違い。Haskell2010の範囲では無理
GHC拡張を使っていいなら

{-# 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
132デフォルトの名無しさん:2010/11/01(月) 20:33:16
>>131
> GHC拡張を使っていいなら
全く問題ないです。

ありがとうございます。
助かりました。
133デフォルトの名無しさん:2010/11/02(火) 10:22:19
「オートマトンの範囲では無理」「CFGの範囲では無理」なら分かるんだが
型システムの表現力を見積もる基準とかってある?
134Perl忍者 ◆M5ZWRnXOj6 :2010/11/04(木) 17:10:49
Haskellで何作ってんの?
























どうせゴミだろ
135100, 103:2010/11/04(木) 18:14:26
>>133
とりあえず、Agdaのような「値」を型構築子の引数にとれるものと、
それができないHaskellのようなものの間には、原理的な違いがあると思う。
136デフォルトの名無しさん:2010/11/04(木) 18:15:11
>>134
論文
137デフォルトの名無しさん:2010/11/04(木) 18:25:42
依存型か
138デフォルトの名無しさん:2010/11/04(木) 20:15:44
計算とリフティングはどうなる。
139デフォルトの名無しさん:2010/11/06(土) 22:50:17
いまさらだけど、RWHをはじめのページから読み出しました。
10章の246ページで挫折しました。
コードが何やってるか分かりません。
140デフォルトの名無しさん:2010/11/06(土) 22:55:09
>>139
なんだ、クイックソートか・・・
よく読めとしか言いようがない。
141デフォルトの名無しさん:2010/11/06(土) 22:58:32
RWHは原著しか読んだこと無い
どんなコード?最初の数行だけでもいいから貼ってくれ
あと節の名前(ボイラープレートをなんちゃらとか、グレイスケールファイルとかそういうタイトル)
142デフォルトの名無しさん:2010/11/06(土) 23:11:14
直前のコードまで理解できただけに、↓が何やろうとしてるのか分かりません。

newtype Parse a= { runParse :: ParseState -> Either String (a, ParseState) }

identify :: a -> Parse a
identify a Parse (\s -> Right (a, s))
143デフォルトの名無しさん:2010/11/06(土) 23:34:25
パーサーモナドの定義を作ろうとしているやつか

newtype宣言の説明は省略するけど
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)

さてこの説明で分からなかったことに対する質問をどうぞ
144デフォルトの名無しさん:2010/11/07(日) 00:01:09
なかなかわかりやすい
145Perl忍者 ◆M5ZWRnXOj6 :2010/11/07(日) 11:43:47
無駄に時間費やしてるゴミ
146デフォルトの名無しさん:2010/11/07(日) 11:57:59
なんだよ、Perlから抜忍したくなったか?
147デフォルトの名無しさん:2010/11/07(日) 18:15:38
145
ワロタ、消えたかと思ったのに
148Perl忍者 ◆M5ZWRnXOj6 :2010/11/07(日) 18:50:16
149Perl忍者 ◆M5ZWRnXOj6 :2010/11/07(日) 18:53:49
ギャグが少ないからまともだろNARUTO
150デフォルトの名無しさん:2010/11/07(日) 19:18:43
>149
http://www.youtube.com/watch?v=itnQMJFRzAI
これきいてます
151デフォルトの名無しさん:2010/11/08(月) 18:45:44
RWHの361ページの上段の説明なんですけど、RandomGenとStdGenの関係について書いてあるみたいなんですけど、ここの日本語が分かりません
だれか解説お願いします。
152デフォルトの名無しさん:2010/11/08(月) 23:10:42
たしかに言語明瞭意味不明な日本語ですが、
StdGenのインタフェースはRandomGenクラスのメソッドで、もしInt乱数に特化したければその定義は変えられるし、本物の乱数装置が手元にあるのなら、それを発生源として本物の乱数を発生させる実装も可能だよ。
ということでは。
153デフォルトの名無しさん:2010/11/09(火) 19:57:26
関数適用の $ って、$ じゃない普通の関数適用で後ろに括弧つけるのと同じ?
括弧はぶいて見やすくしてるだけという認識でおけ?
154デフォルトの名無しさん:2010/11/09(火) 20:19:57
そうだよ

細かいことを言うと、
・後ろだけじゃなくて前にも括弧をつける: (f . g $ x)は((f . g) x)の意
・($)は特別な構文じゃなくてPreludeで定義された演算子(右結合、強度1)
155デフォルトの名無しさん:2010/11/09(火) 20:21:35
強度1じゃなくて0だった
156デフォルトの名無しさん:2010/11/09(火) 20:30:15
getStdRandom の引数が 関数 StdGen->(数値, StdGen)で、
randomR (数値, 数値) の結果が RandomGen->(数値, RandomGen) で、
StdGenがRandomGen のインスタンスだから問題ない、と
StdGen以外でもRandomGenのインスタンスを用意すればいい、と

twoBadRandomsの中に random が説明もなく出てきたんですけど、これは何でしょうか?
157デフォルトの名無しさん:2010/11/09(火) 21:00:29
>>154
サンクス
158デフォルトの名無しさん:2010/11/09(火) 21:21:44
>>156
関数や型、型クラスなどが説明もなく出てきた時は、
まずは標準ライブラリのドキュメントを調べてみてください。
ドキュメントの Index を使えば楽に調べられます。

random 関数は Random 型クラスが定義している関数のひとつです。
randomR 関数もおなじ型クラスが定義している関数のひとつですが、
それとは違い random 関数は乱数の範囲を明示せず、
デフォルトの範囲が使われます。
159デフォルトの名無しさん:2010/11/09(火) 21:51:05
>>158
やっぱり、GHCとドキュメントをインストールして使いながら読まないとダメか…
160デフォルトの名無しさん:2010/11/09(火) 22:02:54
>>159
使わないで 360 ページまで理解できたのなら凄いですね
161デフォルトの名無しさん:2010/11/10(水) 05:17:49
162Perl忍者 ◆V8M/4amdko :2010/11/10(水) 17:13:35
ここみてると毎日無駄な事やっててかわいそうに思えてくる

なーむーん
163デフォルトの名無しさん:2010/11/10(水) 18:07:49
そのレスよりは有意義だと思うぞ
164デフォルトの名無しさん:2010/11/10(水) 22:27:28
Perl忍者こそ無能の固まり
165Perl忍者 ◆M5ZWRnXOj6 :2010/11/10(水) 22:35:18
ここのスレのやつらはある意味親切だから毎日チェックしてんだよ
166デフォルトの名無しさん:2010/11/10(水) 22:44:09
どう考えても無駄なことに没頭する
これこそが贅沢
これこそがステータス

役に立つことしかやる余裕がない人はPerlでメモ帳でも作ってろ
167デフォルトの名無しさん:2010/11/11(木) 11:57:45
Perl忍者こそ無能の極み
168デフォルトの名無しさん:2010/11/11(木) 12:16:02
まぁ、少なくとも就職活動には役に立たないね。
何しろ人事担当も経営者も関数型言語の将来性なんて一つも理解していないのだからw
169デフォルトの名無しさん:2010/11/11(木) 13:29:17
どこの底辺企業だよ
170デフォルトの名無しさん:2010/11/11(木) 13:56:56
>>169
むしろ底辺の一部のベンチャーほど理解してると思うなぁ。
171デフォルトの名無しさん:2010/11/11(木) 14:23:37
研究開発部門ならともかく、ついこないだまで日本語の入出力すらまともにできなかった言語を欲する企業があるとは思えん。
172デフォルトの名無しさん:2010/11/11(木) 14:43:16
>>171
言語が使えるとか使えないという初級レベルの話はしていないと思うなぁw
173デフォルトの名無しさん:2010/11/11(木) 15:34:54
「幾何学なんかやって儲かるのか」だって?
この金やるからどっかに消えろ
                           by ソクラテス
174デフォルトの名無しさん:2010/11/11(木) 15:36:06
まさかの文字コード
さすが馬鹿は発想が貧弱だな
175Perl忍者 ◆M5ZWRnXOj6 :2010/11/11(木) 16:54:19
こいつらはラテン系の数式とか書いちゃってw
方程式とかなw

難しくみせて 実は簡単なことやってる低レベルなやつらねw

バカだから知的にみらたいでしょ?w

そろそろ死んだ方がいいよw
176デフォルトの名無しさん:2010/11/11(木) 17:17:34
涙ふけよ
177デフォルトの名無しさん:2010/11/11(木) 18:16:35
くだらないこと書いて、紙を無駄にするなよ?
あと、忍者熱烈支持!!!
178デフォルトの名無しさん:2010/11/11(木) 18:18:11
>>175
お前自分のレスを読み返してみてどんなことを思う?
179デフォルトの名無しさん:2010/11/11(木) 18:24:13
Perl忍者さんはどのようなお仕事をされているんですか?
180デフォルトの名無しさん:2010/11/11(木) 18:42:50
そこで、”仕事”が出てくる理由がわからない。
銀行員とか書けば良いんだろうか?或は、議員だとか。
何かこう…
181デフォルトの名無しさん:2010/11/11(木) 18:45:01
保安官です.
182デフォルトの名無しさん:2010/11/11(木) 19:16:13
忍者がどのような仕事か知らない人がいるみたいだね
183デフォルトの名無しさん:2010/11/11(木) 19:21:51
大名に仕えて諜報活動するんだろ?
184デフォルトの名無しさん:2010/11/11(木) 19:32:29
忍者の仕事はオナニー
185デフォルトの名無しさん:2010/11/11(木) 19:37:44
186デフォルトの名無しさん:2010/11/11(木) 19:40:46
>>185=Perl忍者
187Perl忍者 ◆M5ZWRnXOj6 :2010/11/11(木) 19:54:12
企業内撮影してアップロードしたら犯罪になる?
188Perl忍者 ◆M5ZWRnXOj6 :2010/11/11(木) 20:01:18
>>176
お前がふけ

>>177
忍者熱烈支持!!! って韓国人みたい

>>178
ほんとに低レベルだと思う

>>179
知り合いが店つくったときのIT化
事務術

>>180
しねw

>>181
死ねw

>>182
大名殺しとかPerl業界の破壊工作
S級犯罪者 ビンゴブックにも載ってるけどな

>>185
外人がわめいてる
189Perl忍者 ◆M5ZWRnXOj6 :2010/11/11(木) 20:08:03
残念ながら俺には5名
影武者がいる
全て共有してるからな 俺を潰したければ本物を見つけてみろ
190デフォルトの名無しさん:2010/11/11(木) 20:21:31
全て共有してるなら、どれも本物だよな
191デフォルトの名無しさん:2010/11/11(木) 20:47:19
>>169
じゃあ九割五分までが底辺だな。w
192デフォルトの名無しさん:2010/11/11(木) 21:02:08
↑亀
193デフォルトの名無しさん:2010/11/11(木) 21:03:01
反知性主義者は進化論が禁止になってる国に帰れや
194デフォルトの名無しさん:2010/11/11(木) 21:03:13
Perl忍者と雑談したい人はPerl忍者スレに書いてください。
話題によるスレの使い分けにご協力願います。

Perl忍者です Perlプログラマになりたいです
http://hibari.2ch.net/test/read.cgi/tech/1284704280/
195デフォルトの名無しさん:2010/11/11(木) 21:05:44
>>194
知恵遅れのPerl忍者。w
196デフォルトの名無しさん:2010/11/11(木) 21:47:44
知性ってなんだよ?
197デフォルトの名無しさん:2010/11/11(木) 22:06:30
198デフォルトの名無しさん:2010/11/12(金) 05:03:08
君達、良い加減にし給え。
199Perl忍者 ◆M5ZWRnXOj6 :2010/11/12(金) 17:14:08
開発経験はなんですか?

「動画プレイヤーの開発です」

好きな言語はなんですか

「PHPとASです」

なにできる?

「Flash使って動画プレイヤー」

俺「プッ(笑)

「Twitterアプリもつくりましたよ」

みせてください

俺「へー(苦笑
200デフォルトの名無しさん:2010/11/12(金) 18:00:45
Perl忍者って、Perl以外に何ができるの?
201デフォルトの名無しさん:2010/11/12(金) 18:01:40
202デフォルトの名無しさん:2010/11/12(金) 20:20:57
関数の中置記法でカリー化を使うことって、
GHC の拡張なんかでできますか?

たとえば次のような感じです。

let f a b c = a * (b + c)
in 2 `f 10` 3

予め g = f 10 としておけば 2 `g` 3 でできますが、
上記のように記述できるかなと。

べつに目的はないです。
これが分かりやすいかどうかも考えてません。
単に Haskell で遊んでて、ふと思ったもので。
203デフォルトの名無しさん:2010/11/13(土) 01:38:19
できません。
204デフォルトの名無しさん:2010/11/13(土) 13:31:57
>>203
素っ気ないな

でも、ありがと
205デフォルトの名無しさん:2010/11/13(土) 15:15:56
諸君、新しい話題は?
206デフォルトの名無しさん:2010/11/13(土) 19:48:27
ありません。
207デフォルトの名無しさん:2010/11/13(土) 21:37:53
ないない。
208デフォルトの名無しさん:2010/11/14(日) 00:07:27
RWHの練習問題の解答例ってどこかにあるのでしょうか?
それとも解答例なんか見るまでもなく簡単にできるものなんでしょうか?
209デフォルトの名無しさん:2010/11/14(日) 00:17:07
"Real World Haskell" answer
なんかでググればいろいろ出てくるでしょ

ネットで読める原書 http://book.realworldhaskell.org/read/
にある各 Exercises のコメ欄にも、回答例のコメントが付いてるのが所々ある
210デフォルトの名無しさん:2010/11/14(日) 12:18:13
URLリストからファイルをダウンロードするスクリプトを書きましたけど、これ、もっと綺麗になりませんでしょうか?

-- ここから
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みたいな関数があったら教えてください
211デフォルトの名無しさん:2010/11/14(日) 14:19:06
>>210
ぱっと見たところ、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 コマンドにどのようなパラメータを渡しているのかは知らない。
公開されている関数の中には、詳細なパラメータを渡す類のものは無さそうだけど、
デフォルトがどうなってるのかは自分で調べてくれ。
ソースを見れば何やってるのか分かるだろうし。
212デフォルトの名無しさん:2010/11/14(日) 14:24:26
>>211
あ、ごめん。
wgetMain 関数は空リストだったり成功したら ExitSuccess を「ひとつ」返すのか。
それなら forM_ や forM では意味無いね。
成功や失敗のリストを返すのなら forM を使えばいいけど。

ごめん、>>211 の前半は無視してくれ。
213デフォルトの名無しさん:2010/11/14(日) 16:29:04
wget で画像のダウンロード失敗して ExitFailure を受け取ったURLのリストをリストに保存しようと思ったら、URLに画像が存在しなくても 404.html をダウンロードして ExitSuccess を返してきちゃう
214デフォルトの名無しさん:2010/11/14(日) 16:48:45
>>213
(h, b) <- wget' "http://・・・hoge.gif" [] []

とやって、ヘッダの内容を確認してもダメだった?

それでもダメなら、b の先頭数文字くらいのマジックコードで、
画像ファイルかどうかを判別するとか
215デフォルトの名無しさん:2010/11/14(日) 16:54:42
curl -I <404.htmlを返すurl>でどんなレスポンスコードがくる?
もし404じゃないのが来るようなら自前で判断するコード書く必要がある
216215:2010/11/14(日) 16:55:50
ごめんスルーで
217デフォルトの名無しさん:2010/11/14(日) 17:57:58
>>210
HTMLテキストファイルから画像の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
218デフォルトの名無しさん:2010/11/14(日) 18:09:43
>>217
相対 URL も忘れずに
219デフォルトの名無しさん:2010/11/14(日) 18:11:42
>>217
IMG タグ内の SRC だけを調べた方がよくないか
220デフォルトの名無しさん:2010/11/14(日) 18:18:01
>>217
相対パス名ガン無視だから、ちゃんと動くのは二次裏だけだと思う
二次裏は、junとかmarとか画像を置いてるサーバを分けてて、全部絶対パス名で書いてるから
221デフォルトの名無しさん:2010/11/14(日) 20:23:31
www.haskell.orgが見れないのですが、いつからでしょうか。
どなたかご存知ないでしょうか?
222デフォルトの名無しさん:2010/11/14(日) 20:33:10
>>221
一昨日までは見てたから、それ以降からだろ

良くある、今までも何度もあった
待ってれば数日で見られるようになる
223デフォルトの名無しさん:2010/11/14(日) 20:34:35
昨日の夜は見られなかったよ
224デフォルトの名無しさん:2010/11/14(日) 21:19:55
>>222 >>223
ありがとうございます
wxHaskellかGtk2HS試したかったのですが、待つことにします
225デフォルトの名無しさん:2010/11/14(日) 21:31:59
>>224
どちらも今問題なく hackageDB から落とせるが?
226Perl忍者 ◆M5ZWRnXOj6 :2010/11/14(日) 21:48:51
さきりさ っていうやつしね

227Perl忍者 ◆M5ZWRnXOj6 :2010/11/14(日) 21:56:00
hageDBみてええだな
228デフォルトの名無しさん:2010/11/15(月) 07:31:16
Perl忍者ぺろぺろ
229デフォルトの名無しさん:2010/11/15(月) 20:43:25
Haskell の最適化にまつわる話やテクニック、注意などを集めて紹介している
本やサイトはありませんか。

例えば、末尾再帰の形の関数は引数が正格でなければ効率は上がらないとか。
計算量や必要な(メモリ)空間などの測り方とか。

アルゴリズム系の本やブログなんかで少し紹介されてはいますが、
まとまった情報というのがなかなか見当たりません。

日本語・英語どちらでもかまいません。
230デフォルトの名無しさん:2010/11/15(月) 21:24:33
すぐ見つかったのはこれ
http://www.slideshare.net/tibbe/highperformance-haskell
http://book.realworldhaskell.org/read/profiling-and-optimization.html

haskell.orgのwikiにも記述があったと思うけど、まだ落ちてるな
231デフォルトの名無しさん:2010/11/15(月) 21:35:15
>>230
すいません、紹介しているという言い方が悪かったです。
カタログ化されてるといいなぁと。
(どこもやってなかったら、自分でやってみようかなとは、ちょっと思ってますが)

紹介していただいた前者のページは初めて知りました。
これは、上のスライドを表示しながら、
ページ下の台詞を講演者が喋っていたというイメージですか。
初めの方をちらっと見ましたが、扱ってる話題が多そうなので、
これからじっくり見てみます。

後者の方は原著(ネット)も和訳も読みましたが、浅い感じでした。
なんというか、少なくともこのトピックに関しては
詳細はウェブで、論文で、他書で、公式ドキュメントでという感じでした。
232デフォルトの名無しさん:2010/11/15(月) 21:43:31
>>230
忘れてました。

紹介、ありがとうございました。
233デフォルトの名無しさん:2010/11/16(火) 10:19:02
GHC 7.0.1
234Perl忍者 ◆M5ZWRnXOj6 :2010/11/16(火) 17:44:26
イモリ4GBだけどネトゲはサクサクうごきますか?
235デフォルトの名無しさん:2010/11/17(水) 05:46:15
学ぶのも大変なのに,性能までゴミだと?
そんなクズみたいな言語は使いたくありません.
http://shootout.alioth.debian.org/
236デフォルトの名無しさん:2010/11/17(水) 06:28:35
実は俺どうこのベンチを解釈したらいいかよくわかんないんだけど
リンク貼っとけば勝手に話を膨らませてくれるだろう

まで読んだ
237デフォルトの名無しさん:2010/11/17(水) 19:29:33
Haskell十分すぎるほど速いじゃん
あとLuaが意外と上位なんだね
238デフォルトの名無しさん:2010/11/17(水) 19:31:35
ほんとだ、LuaがJavaより速い(こともある)のは知らなかった
239デフォルトの名無しさん:2010/11/17(水) 19:43:42
まぁ、そこそこの努力で十分な速さが出るならいいよな

いろんな最適化テクニックを駆使しなければならないとか、
またそのためにソースが見難くなるのなら問題だけど
240Perl忍者 ◆M5ZWRnXOj6 :2010/11/17(水) 21:24:00
お前らまだHaskellやってんの

死んだ方が良いよ

親がかわいそう
241デフォルトの名無しさん:2010/11/17(水) 23:46:15
この忍者の親が可哀想だわ
242デフォルトの名無しさん:2010/11/17(水) 23:55:10
まさか息子が忍者やってるとは思いもしないだろうなw
243デフォルトの名無しさん:2010/11/18(木) 00:37:04
>>242
たしかにwww
244Perl忍者 ◆M5ZWRnXOj6 :2010/11/18(木) 22:15:47
いテレパシーがとんできました

haskellスレから

誰かいまテレパシーをおくったか?

お前らかわいそうだよ
haskellやって ゴミ掃除やってるレベルだろ
245デフォルトの名無しさん:2010/11/19(金) 08:40:24
Luaが速いというか、LuaJITが速いみたい
Haskellが今より20%くらい速くなると、ほぼJavaの水準になるね
246デフォルトの名無しさん:2010/11/19(金) 10:01:04
じゃあ誰が20%速くしてくれんだよ!
Ruby高速化したあの少年連れて来い!
247デフォルトの名無しさん:2010/11/19(金) 10:03:03
RWHの次に読むべき英語の書籍ってなんだっけ?
248デフォルトの名無しさん:2010/11/19(金) 10:17:20
何がしたいの?
249デフォルトの名無しさん:2010/11/19(金) 10:45:25
万能感を錯覚したいです
250デフォルトの名無しさん:2010/11/19(金) 10:55:55
それならRWHとか読んでないで然るべきクスリを使うべき
251デフォルトの名無しさん:2010/11/19(金) 11:21:25
では質問を変えます
最も新しく発売されたHaskellの書籍は何ですか?
252デフォルトの名無しさん:2010/11/19(金) 12:37:07
>>251
Concurrent Haskell
(ISBN-13: 978-6133152977)

たぶん、これが最新だと思う
内容は知らん
253デフォルトの名無しさん:2010/11/19(金) 12:53:02
あ〜これだったかなぁ?違ったかなぁ?
前スレの末尾までの時点で最新だった奴だと思うんですけどね
254デフォルトの名無しさん:2010/11/19(金) 18:09:39
>>253
じゃあこれか

Pearls of Functional Algorithm Design
(ISBN-13: 978-0521513388)
255デフォルトの名無しさん:2010/11/19(金) 20:30:16
>>254
ああこれだ!多分これ!
あり^^
256デフォルトの名無しさん:2010/11/19(金) 20:54:48
次のような型クラスと関数があるとします。

class 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 関数をそのまま使ってそのような関数を作ることは
できないのでしょうか(型シグネチャをどこかに明示して)。
257デフォルトの名無しさん:2010/11/19(金) 22:03:00
>>256
無理
そもそもtransの型が曖昧でコンパイル通らない
258デフォルトの名無しさん:2010/11/19(金) 22:25:34
>>257
では、

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 といった型のみが違うだけなのですが、
どうにかしてこの型をパラメータとして指定できる関数は作れないものでしょうか。
259デフォルトの名無しさん:2010/11/19(金) 22:53:59
>>258
transの型シグネチャに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
260デフォルトの名無しさん:2010/11/19(金) 23:13:10
>>259
実現するには、今の Haskell(GHC)では無理矢理やるしか方法が無いんですね。
GHC の拡張機能で、もっとこう特別な構文なんだと一目瞭然な記述で、
スマートに型を伝える手段があるのかなと思ってました。

ソースを見た時に、なぜそのような記述になってるのか
意味を理解しにくくなりそうですね。

今回は QuickCheck 用のソースで、どのようにテストしているか、
その内容を分かりやすくソースで示す必要があるので、
今回は諦めることにしました。

せっかくのアドバイスですが、すいません。
261デフォルトの名無しさん:2010/11/20(土) 06:57:08
>>254の書評ください
262Perl忍者 ◆M5ZWRnXOj6 :2010/11/20(土) 09:27:50
tsuwabukiてめえこいよ

haskell板のtsuwabukiっていうやつがSkypeにきたぞ
263Perl忍者 ◆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/
にご連絡ください
264デフォルトの名無しさん:2010/11/20(土) 11:50:53
いいかげんこのアホ忍者通報されないかな
Haskellスレと無関係なことばっかじゃん
265デフォルトの名無しさん:2010/11/20(土) 13:34:03
>>261
積んでたが、これから読んでみる
書評は2、3ヶ月待ってくれ

途中で色々質問するかもしれん
266デフォルトの名無しさん:2010/11/20(土) 16:17:58
>>264
カルトスレは板違いだろうが
267デフォルトの名無しさん:2010/11/21(日) 11:35:19
>>266の村って進化論禁止してそう
268Perl忍者 ◆M5ZWRnXOj6 :2010/11/21(日) 19:46:38

269Perl忍者 ◆M5ZWRnXOj6 :2010/11/21(日) 19:53:46
ん  こまねち
270デフォルトの名無しさん:2010/11/21(日) 20:33:39
>>267
進化論は板違いだろ
しかし、このスレの奴は進化論が好きだな。
271デフォルトの名無しさん:2010/11/21(日) 20:41:53
>>1
関連スレ

人工知能を作ろうver0.0.6
http://hibari.2ch.net/test/read.cgi/tech/1263645019/
272デフォルトの名無しさん:2010/11/22(月) 00:05:42
こういう書き方ってできないんだな

hoge [] = error "hoge: empty list"
hoge    = head . tail

せっかくポイントフリーで綺麗に読みやすく書けたと思ったのに、
エラー処理を入れたとたんに仮引数を明示しなければならないなんて
273デフォルトの名無しさん:2010/11/22(月) 08:22:41
>>267
忍者はスルーで”カルト”には反応しちゃうんだ....
274tsuwabuki:2010/11/23(火) 10:27:28
Haskellやってますが
アルバイトで生計たててます
275デフォルトの名無しさん:2010/11/23(火) 16:56:14
「Pearls of Functional Algorithm Design」を読み直してるんだが、
やはり 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 の時に検索の必要がないという意味も、全く分からないんだ。
276デフォルトの名無しさん:2010/11/23(火) 17:03:27
その本読んでないから見当違いかもしれんが、m x n rectangleの事じゃないの。
277デフォルトの名無しさん:2010/11/23(火) 17:13:06
http://www.springerlink.com/content/6837654p2449501k/
look insideでそこの直前まで読めるね

search Xの意味は「Xを探す」じゃなくて「Xから何かを探す」
Xは探す対象じゃなくて探索範囲
探す対象はたぶん「f (x,y) = zを満たす(x,y)」じゃね
278デフォルトの名無しさん:2010/11/23(火) 17:24:41
>>276
>>277
ありがと

> search Xの意味は「Xを探す」じゃなくて「Xから何かを探す」

マジですか!
今まで生きてきて、X を探すという意味しか無いとずっと思い込んでた。
from の意味が暗黙的に含まれている事もあるのか、目から鱗だ。
英語って奥が深いな・・・

認識を改めてちょっと読み直してみる
279デフォルトの名無しさん:2010/11/23(火) 17:38:21
>from の意味が暗黙的に含まれている事もあるのか
辞書を引けば分かるけど常にこの意味だよ
「X(物体)を探す」ならsearch for X
280デフォルトの名無しさん:2010/11/23(火) 17:48:08
うそん
search a needle in a haystack とか言わないか
281デフォルトの名無しさん:2010/11/23(火) 17:53:38
>>279
認識を新たにして読み直してみたが、そうすると今度は直後の

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) までが検索範囲になると思ってるんだが、勘違いだろうか。
(正確にはもう少し範囲を狭められるという話題が直前にあったが)
282デフォルトの名無しさん:2010/11/23(火) 18:10:14
>>281
m 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
283デフォルトの名無しさん:2010/11/23(火) 18:57:50
>>282
> m x n rectangleと言ってるんだから、mとnは座標じゃなくてサイズだろ

それなら、「探す対象はたぶん「f (x,y) = zを満たす(x,y)」じゃね」と矛盾しないか?

例えば f(0,0)=z だったら、探す対象は (0,0) のはずなんだが、
それは幅 m 高さ n の rectangle の範囲のどこにあるか
と考えた時に「アレ?」って思わない?

なんか、俺が何か大きく勘違いしている気がするんだが・・・
284デフォルトの名無しさん:2010/11/23(火) 19:20:41
>>277で読める分だけ読んだけど、別に矛盾しないような
探索範囲である長方形を再帰的に分割・縮小していくアルゴリズムで、
その過程で現れるサイズm*nの領域を探索するコストの話をしてるんだから、おかしいところはないはず
285デフォルトの名無しさん:2010/11/23(火) 21:58:31
>>284
例えば、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 なんじゃないの?
286デフォルトの名無しさん:2010/11/23(火) 22:01:05
>>285
ごめん、例のパラメータ値がおかしかった

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 ...
287デフォルトの名無しさん:2010/11/27(土) 13:30:58
関数fから2つの値を返して
それらにletで一つずつ変数を束縛したいのですが
どんな風に書けば良いでしょうか?
288デフォルトの名無しさん:2010/11/27(土) 13:39:56
f = (1,2)
ff = let
a = fst f
b = snd f
in
[a,b]
みたいな?
289デフォルトの名無しさん:2010/11/27(土) 14:08:56
f = (1, 2)
g = let (a, b) = f in (aとbを使う式)

で束縛できるでしょ。
290デフォルトの名無しさん:2010/11/27(土) 21:39:17
ありがとうございます。

>>288
なるほど、どうも以前やってた言語のイメージで
「2度呼び出されるのはマズいのでは」と感じてしまって

let tmpList = f
in
  let
    a = fst tmpList
    b = snd tmpList
  in ...

みたいなことを考えてしまいました。
でも Haskell の場合、引数が同じなら結果も同じ…と考えれば
そんなことは杞憂かも知れませんね。


>>289
そんな書き方が出来たのですね。
タプルは失念してました。精神的にも良い感じなのでこっちで行こうと思います。
291デフォルトの名無しさん:2010/11/28(日) 17:56:12
>>290
仕様上は保障されていないと思うけど、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方式」で良いと思う。
292デフォルトの名無しさん:2010/11/28(日) 19:05:13
>>291
それは、書籍なんかでもよく取り上げられるトピックなんだが、
同じ関数を同じ引数値に適用しても、そのつど評価されるんだよ。
同じ引数値だからキャッシングされてるだろうと考えてはいけない。
それはプログラマ自身がキャッシングの仕組みを作る必要があるんだよ。

一般になんていう名前のテクニックだったかな、忘れてしまった。
キャッシングじゃなくて、もっと別の名前があったような気がしたが。
293デフォルトの名無しさん:2010/11/28(日) 19:18:03
memoize のことか?
294デフォルトの名無しさん:2010/11/28(日) 19:53:53
そう、それだ

memoize って発音しにくいよな
295デフォルトの名無しさん: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"
296デフォルトの名無しさん:2010/11/28(日) 21:29:05
ならない

do let !i' = concat l; return ()

concat l `seq` return ()
と等価だけど、seqは左辺を最上位の構築子が明示される形(WHNH)までしか簡約しない。この例だと、
concat (take 1000 (repeat (take 1000 $ repeat 1)))

1 : 何か
まで評価したらそこで終わってしまう
297デフォルトの名無しさん:2010/11/28(日) 22:31:31
>>296
やはりそうか
だからリストの要素数を極端に増やしても 0.0s のままなんだな

let a = concat l
let !b = length a



let !b = length l -- (l は concat 済み)

の2つの処理の前後時間の差分を測り、さらにそれらの差分を測れば、
concat の処理速度を測れたと考えていい?
298100, 103:2010/11/29(月) 01:57:28
オレは、>>296とは別人物ね。

たしかに、そういうような比較をすれば、ある意味では、concat の処理速度を測れたといってよいと思う。
「ある意味では」というのは、動的なメモリ確保とか、遅延評価のクロージャを処理するコストも測定結果に含まれてしまうけども、ということ。

ただ、オレもそういうことを以前は気にしていたけど、いまはそのような評価はあまり意味がないんじゃないかと思う。
なぜなら、concatの処理速度をそのように計測したところで、実際のアプリケーションではどうせ遅延評価されるわけで、その「concatのコスト」がまるまるアプリケーションのコストになるかどうか分からないから。

もし、特定のアプリケーションで、何かの処理をするまえに必ずconcatの結果をすべて評価しておきたいとかいうことであって、しかもその処理速度が気になるようであれば、
リストのような遅延評価向きのデータ構造とか、concatのような遅延評価前提の関数を使うんじゃなくって、
正格データ型とそのための専用関数を用意するべきじゃないかと思うんだ。

299298:2010/11/29(月) 02:28:00
例えば、こんな感じ。

data 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
300デフォルトの名無しさん:2010/11/29(月) 07:37:15
>>298-299
非リアルタイム3Dレンダラーを分割統治法で書いてる。
イメージを縦横いくつかのブロックに分けてそれぞれレンダリングし、
最後にそれらを一つのイメージに合成する。

で、合成する時に、Array ブロックから Array 単体に合成した方が速いのか、
List ブロックから List ブロック 単体か、Array ブロックから List 単体か・・・
その時に使う合成戦略(関数の使い方など)はどれが速いのか・・・
といろいろ実験してた。

> いまはそのような評価はあまり意味がないんじゃないかと思う。

最初 Array で単純に合成しいてたら、合成処理時間だけでけっこうかかってた。
正格に何ミリ秒かかったとかいう数値はそれほど必要ないけど、
レンダリング全体の時間に対する割合くらいはパーセンテージで欲しいんで。

> 必ずconcatの結果をすべて評価しておきたいとかいうことであって

すまん、まだ遅延評価しておかなきゃならないんだ。
合成後もそれを一部テクスチャにして別のレンダリングをしたりするから、
無駄なレンダリング処理を省きたい。

ただ、正格評価用のデータ構造と関数を別に用意しておくという考え方は参考になった。
別の部分の処理で絶対に必要になるから覚えておく、ありがと。
301デフォルトの名無しさん: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 を使用しています。
302デフォルトの名無しさん:2010/11/30(火) 21:50:32
>>301
-ddump-simplオプションで最適化済みのGHCの中間コードが見られる
その例のままだと、fが小さい関数だから-Oでインライン化されてb = T 4 18まで最適化される
インライン化できないほど大きいfの場合でも、worker/wrapper変換という最適化がかかるから
すぐ捨てるような中間データは排除してくれることが多い
303デフォルトの名無しさん:2010/11/30(火) 22:08:59
f (T x y) = T (x+x+x+x+x+x+x+x+x+x+x+x+x+x) (y+y+y+y+y+y+y+y+y+y+y+y+y)
とか、インライン化しない例
304デフォルトの名無しさん:2010/11/30(火) 22:20:44
>>302
-ddump-simpl-stats オプションを付けてコンパイルした時、
RuleFired の項目に worker/wrapper が無ければその最適化は効いていない、
つまり中間のデータ型は無駄に構築されているという判断でいいでしょうか。
305デフォルトの名無しさん:2010/11/30(火) 22:38:33
>>304
worker/wrapperはRule(書き換え規則)じゃないから関係ないはず
306デフォルトの名無しさん:2010/11/30(火) 22:45:28
>>305
最初 -ddump-simpl しても何も出力されなかったから、
とりあえず最適化されたかの目星を付けようとして >>304 と訊きましたが、
今分かりました。

-ddump-simpl の出力を見て、例えば >>301 の例だと、
b が参照している T の中身を辿っていった先が定数になっていれば、
最適化がちゃんと働いたということですね。
307デフォルトの名無しさん:2010/12/02(木) 15:37:11
UArrayからByteStringへの変換の効率の良いやり方ってありますか?
つまり、

> uArrayToByteString :: UArray Int Word8 -> ByteString
> uArrayToByteString a = pack . elems

という関数を、リストを経由しないように実装したいんですが。
308デフォルトの名無しさん:2010/12/02(木) 17:18:24
uArrayToByteString :: UArray Int Word8 -> ByteString
uArrayToByteString 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)

こんなもんかな?
309デフォルトの名無しさん:2010/12/02(木) 20:52:55
{-# OPTIONS_GHC -fglasgow-exts #-}
import 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)
310デフォルトの名無しさん:2010/12/02(木) 21:40:22
>>309
それは駄目だろ
第一にpinされていないByteArray#に対してbyteArrayContents#を使っているのでGCでbarrが動いたら終了
第二にunsafePackAddressLenは呼び出し側がメモリを管理することを要求するけど、
それを怠っているのでbarrがGCに回収されたら終了
311309:2010/12/03(金) 23:02:34
>>310
UArrayとByteStringは内部表現同じっぽいし
ゼロコピーでいけるんじゃね?と思ってでっちあげてみたんだけど、
やっぱりGCでこけるか。
いやまあ、そんな気はしてたんだけど。
312デフォルトの名無しさん:2010/12/06(月) 08:35:09
初歩的な質問で申し訳ないですが、
sum . map (2^) $ [0..9]
sum $ map (2^) $ [0..9]
sum $ map (2^) [0..9]
これらの違い(コスト?)を教えてください。

そもそも$演算子のありがたみが(カッコが減る以外に)思いつかないのですが、
Real World Haskellの索引をみても($)はfmapのところに飛ばされるだけで、
どこに解説してあるのか不明です。
よろしくお願いします。
313デフォルトの名無しさん:2010/12/06(月) 11:53:39
>>312
違いはないと思っていい
最適化しない処理系だとコストが微妙に違うけど、sumとmapとenumFromToのコストに比べたら無視できる

>そもそも$演算子のありがたみが(カッコが減る以外に)思いつかないのですが、
基本的にそれだけ
あとは高階関数に($)を渡すとか
314デフォルトの名無しさん:2010/12/06(月) 15:35:04
>>312
括弧が減るのは結構ありがたいよ。試しに全部括弧で書いてみるといい。
( はまだその場で書くからいいが、
) はまとめて書くことが多くなるから、数を数えながら書かなきゃならなくなる。

まあエディタの対括弧表示の機能で何とかなるっちゃあなるんだが…
括弧の数で有名なLisp系は実際エディタで何とかしてるみたいだし。
315デフォルトの名無しさん:2010/12/06(月) 15:49:30
そんな方法で括弧減らしてたら関数型使う意味なくね
316デフォルトの名無しさん:2010/12/06(月) 16:09:50
>>315は括弧を書くために関数型言語を使ってるの?
317デフォルトの名無しさん:2010/12/06(月) 16:36:29
そうだよ
318312:2010/12/06(月) 16:59:21
>>313,314
ありがとうございます。ひとまず腑に落ちました。

>>317
Lisp使うと幸せなんでしょうね。
319312:2010/12/06(月) 19:18:13
でも、これってコーディング規約をつくらないと、
他人のを読んだときに混乱しそう。

みなさんはどういう規則で$を入れていますか?
それを規約として定義できますか?

>>312
の例だとmap一発ですが、二発三発なめる場合は
合成を使った方がいいようにも見えます。
320Perl忍者 ◆M5ZWRnXOj6 :2010/12/06(月) 20:02:31
かわいそう・・・
321デフォルトの名無しさん:2010/12/06(月) 20:04:50
どれでも普通に読めるので統一されてなくても気にならないけど、一応俺のスタイルはこんな感じ
- 括弧の代わりに$を使えるならなるべく使う
- 複数行にわたる括弧を消せるときは必ず使う
- 見た目の対称性のために$を使わないことがある(「mappend (f x) (g y)」みたいな場合 )
- 必要のない$は使わない(例えば「f $ g $ x」の右側の$)
- $の左辺に関数合成を置かない(例えば「f . g $ x」)
322デフォルトの名無しさん:2010/12/06(月) 20:12:36
>>315,317
        /⌒  ⌒\         ━━┓┃┃
       /(  ̄)  (_)\         ┃   ━━━━━━━━
     /::::::⌒(__人__)⌒:::: \         ┃               ┃┃┃
    |    ゝ'゚     ≦ 三 ゚。 ゚                       ┛
    \   。≧       三 ==-
        -ァ,        ≧=- 。
          イレ,、       >三  。゚ ・ ゚
        ≦`Vヾ       ヾ ≧
        。゚ /。・イハ 、、    `ミ 。 ゚ 。

>>319
そんなに混乱しないと思っているので、基本的に気分次第。
ただ、その気分次第の結果として、最も大きな式(?)の最後の括弧を減らせるかぎりは$を入れ、そうでないときは入れない、という傾向があると思う。

例えば

... = f1 (f2 (f3 a)) というときは
... = f1 $ f2 $ f3 a にしがち。

... = f1 (f2 (f3 a)) b のときは
... = f1 (f2 $ f3 a) b と書けはするけど、それはあまりしない。
323デフォルトの名無しさん:2010/12/06(月) 20:20:31
> - $の左辺に関数合成を置かない(例えば「f . g $ x」)
以外はこっちと同じ方針だ
324デフォルトの名無しさん:2010/12/06(月) 22:13:41
>>312
カッコを減らす以外にメリットはないでよ。$なかったらLispみたいになっちゃうから、
俺は結構好き。
325デフォルトの名無しさん:2010/12/07(火) 10:54:58
関数名が長くなりすぎるのは設計が悪いんかなあ。
getNthHogeOfHageInHige
みたいな。
326デフォルトの名無しさん:2010/12/07(火) 11:19:42
data D = A Int Int | B String String
x :: D
で、x が B String String であることがわかっているときに、
f (case x of B s _ -> s)
というのをもっと簡便に書くにはどうしたらいいでしょう?
327デフォルトの名無しさん:2010/12/07(火) 12:54:03
>>325
一概には言えないが、関数型言語の関数(function)は、
手続き型言語の手続き(procedure)とは違って静的なものなので、
たいていは動詞ではなく名詞を使うように頭を切り換えると良い場合が多い。
だから、「get」「put」「set」「conv(ert)」などのような動詞が
なるべくなら接頭辞として付かないような方向で考える。

また、修飾語句はできる限り引数の型で表した方がスッキリする。
例えば「n番目の」というのは標準ライブラリを見ても関数名には無いと思う。
同じ役割の関数で番号指定できるものとできないものが有るなら、
(必要なら)私なら関数名の後ろにNを付けるか付けないかで区別するが、
その前にそもそも番号指定版だけで済ませられないか考える。

「〜の中の」とか「〜の」というのも、まず引数の型で表すことを考える。
「〜」に当たるものが色々あるのなら、それらをひとつの型クラスで表し、
その型クラスに対する「の中の」関数だけの状態にして、
関数名には「〜の中の」という言葉は入れないようにする事を考える。

「〜の中にある〜の中の」というように入れ子状に続くのは論外。
この場合は関数をいくつかに分けて、ひとつの関数で「〜の中の」は
多くても一つだけの状態にするように考える。

ただ、分けたそれぞれの関数が独立では使われず、
いつも「〜の中にある〜の中の」という状態で使われる場合は、
関数を分けずにひとつの関数で表して、
関数名としては一番外側の「〜の中の」だけを表した方がいい。
しかしこの場合、そもそも設計がおかしいことの方が多いが。
328デフォルトの名無しさん:2010/12/07(火) 13:06:09
>>326

data D = A Int Int | B { foo :: String, bar :: String }
f (foo x)
329326:2010/12/07(火) 13:14:04
>>328
あぁぁ、フィールドラベルっていうのはそんなふうに使うのですね。
よくわかりました。ありがとう。
330デフォルトの名無しさん:2010/12/07(火) 14:28:28
>>327
大変おもしろく読んだけれど、ここは気にいらない。
>その前にそもそも番号指定版だけで済ませられないか
常に要求された通り、または、心に浮かんだ通り、
定義するのが基本だと思う。
331327:2010/12/07(火) 18:11:06
>>330
そりゃ考え方は人それぞれだ。

ひとの考え方と自分の考え方の何がどのように違うのか、
何故違うのか、互いの色んなケースでのメリット・デメリットは何か、
色々比較した上でそっちの方がいいと思うのならそれでいいんじゃないか。
332327:2010/12/07(火) 18:54:04
今ふと思ったが、番号指定版と指定しない版が必要なら、
「指定しない版だけ」を作る方針の方がいいかもしれない。

順序付き集合を返す「番号を指定しない版の関数 hoges」と、
「何かの順序付き集合から特定番号の要素のみを返す関数 pick」に分ける。
例えば3番目の hoge が欲しかったら pick 3 hoges と記述する。

そうすると、pick 関数は他にも流用できるし、関数名を短くできる。
また、式を右から読んでいって何を表す式なのか、
比較的分かりやすいんじゃないかな。

これなら、番号を指定する必要がない時は hoges だけでいいから、
「常に要求された通り、または、心に浮かんだ通り、定義」できると思う。
333デフォルトの名無しさん:2010/12/07(火) 20:07:15
f . g $ x
これ良くないの!?
寧ろ積極的にこう書き換えてた!
334デフォルトの名無しさん:2010/12/07(火) 20:45:59
状況による。
どの書き方がわかりやすいかは一概に言えない
335デフォルトの名無しさん:2010/12/07(火) 20:47:07
状況というよりスタイルじゃないか?
どの状況でどれを使っても大差ないよ
336デフォルトの名無しさん:2010/12/07(火) 20:51:04
状況によっって使い分るスタイルかもしれんじゃないか
337デフォルトの名無しさん:2010/12/07(火) 21:36:11
>>333
単なる好み(カッコよく言えば哲学)の問題だ。
私の場合はその書き方は気持ち良くないと感じる。
どちらかと言えば f (g x) の方が気持ちいい。
なぜなら、関数 f が適用するモノが分かりやすいと感じるから。
でも、その差は微々たるものだ。

そもそも、「分かりやすさ」というもの自体が個人の物差しであって、
その物差しをチーム内で(たいていは強引に)揃えるのが「コーディング規則」だ。
個人でプログラムしてるのなら、好きにすればとしか言いようがない。
338デフォルトの名無しさん:2010/12/07(火) 22:12:49
f . g $ x
は自分なら、あとでポイントフリーにしたいけど、
わかりやすさのためにまず変数を書いておくときに使うかな。

書き終わったらこの形は残らない。
339デフォルトの名無しさん:2010/12/07(火) 22:46:56
>>338
後でポイントフリーにするのはどうして?
仮引数が残っているよりも、ポイントフリーの方が
分かりやすかったり、見やすかったりするから?

もしそうなら、それは「わかりやすさのためにまず変数を書いておくとき」
の場合の「わかりやすさ」とは違う質のもの?
340デフォルトの名無しさん:2010/12/07(火) 23:00:35
関数定義で複数のパターンマッチがある場合、引数の数を揃えなければならないからとか?
341デフォルトの名無しさん:2010/12/08(水) 00:57:11
>>339
書くときと読むときのわかりやすさが違うのかも。
書くときは仮引数xをデータとしてそれへの関数適用で考えて、
読むときは型宣言を手掛かりとしつつ右から左へ合成された関数の流れを見る。
だから、完成して型検査を通ったら、読みやすいようにポイントフリーにして
書き終わる。(左辺のxと、"$ x"を削除する)

はじめからポイントフリースタイルで書くのはちょっと難しい。
342デフォルトの名無しさん:2010/12/08(水) 07:30:50
>>341
> 読むときは型宣言を手掛かりとしつつ右から左へ合成された関数の流れを見る。

ポイントフリースタイルだからこその分かりやすさというのが、
この説明ではまだよく分かんないな。
これなら最後の $ x が有っても無くても大して変わらなくない?

> はじめからポイントフリースタイルで書くのはちょっと難しい。

つまり逆で、最後にわざわざポイントフリーにしなくてもいいんじゃない?
343デフォルトの名無しさん:2010/12/08(水) 07:53:41
長い式を書くときに、左から書いていける人か、右から書いちゃう人かで違うとか
344342:2010/12/08(水) 07:56:31
そういう私もポイントフリーを多用してるけど、
それは初めからポイントフリーで考えている時だけ。

関数作成を考え始める時点で、どのような役割の関数か、
つまり「何から何への写像」を作ろうとしているのかは分かってる。
これがメイン引数となる。
それを実現するのに必要な情報、サブ引数も洗い出せば分かる。
写像の形を元に、どの関数をメインに使って実現させるのか方針が立てられる。
(map なのか、filter なのか、その組み合わせなのか、既存の自作関数かなど)
この時点で自然にポイントフリーで考えてる。
(ポイントフリーにできない場合も、ごく自然に非ポイントフリーで考えてる)

あとは、サブ引数を使って肉付けし、ソースを記述する時点では、
ポイントフリーになってる。

あとからポイントフリーにリファクタリングするケースはほとんどない。
そういうケースは自分の設計力の無さに多少落ち込む。
345デフォルトの名無しさん:2010/12/08(水) 07:59:22
346デフォルトの名無しさん:2010/12/08(水) 09:38:20
Eulerが見たらなんて言うだろう
347デフォルトの名無しさん:2010/12/08(水) 09:51:59
おいらにゃ関係ねぇ
348デフォルトの名無しさん:2010/12/08(水) 13:07:12
349デフォルトの名無しさん:2010/12/08(水) 13:25:05
>>347の人気に嫉妬
350デフォルトの名無しさん:2010/12/09(木) 00:05:49
>>344
自然にポイントフリーで考えてるってのは「関数型脳」が既に身についているってことでしょ。
俺も初めは>>342みたいに、関数を書いた後からポイントフリーに
直してみるってことをやってたよ。

手続き型言語に慣れた脳味噌には、初めから関数合成で考えるのはちと難しいんだよね。
だから、まずは手続き的に「値を順番に変形させていく過程」として捉えて関数を書いてから
後からポイントフリーにすることで、改めて関数合成として捉え直してみるっていう感じだな。

そういう修行wを通じて、段々と「自然にポイントフリーで考え」られる脳味噌が
できていくんじゃないかな。っつか、俺の場合はそう。
351デフォルトの名無しさん:2010/12/09(木) 01:59:40
グーグル検索

念のためうぷ(´・ω・`)まわいが重要


グーグル検索

やらなくてもやられるし 日本語以外話せないし


テレビやネットで説明
352デフォルトの名無しさん:2010/12/09(木) 07:32:50
>>350
そういう関数型と手続き型を比較しつつ、
関数型の思考法を徹底的に解説する本があれば面白そうだ。
関数型らしさとは何か、と複数の著名人にインタビューした記事とか。

「Introduction to Functional Programming(関数プログラミング)」や
「Fun of Programming(関数プログラミングの楽しみ)」などは
そういうのとはちょっと違う感じだった。
(後者はわりと近いが)
353デフォルトの名無しさん:2010/12/09(木) 11:46:32
>>350
俺も未だに手続き脳なんで、すごく解る。
「自然に書く」と、およそポイントフリーには向かない設計になってるんよね。
354デフォルトの名無しさん:2010/12/09(木) 12:06:03
>>353
ストリームを意識せよ
355デフォルトの名無しさん:2010/12/09(木) 12:12:58
流れを切ってすみません。

Haskell 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
とすれば、望みのことができますが、こうするしかないものなのでしょうか?
356デフォルトの名無しさん:2010/12/09(木) 12:20:35
名前変えればいいだけじゃん。
なんで y にしたいの
357デフォルトの名無しさん:2010/12/09(木) 12:24:10
>>355
そうするしかない
内包表記に限らず動的にパターンを作る方法はない
358デフォルトの名無しさん:2010/12/09(木) 12:42:40
>>356
えっと、意味がよくわかりません。

>>357
ありがとうございます。そういうものなのですね。
パターンは静的にしか書けないという規則だと思えば、すっきりしました。
359俺用謹言集:2010/12/09(木) 16:44:36
・パターンは静的にしか書けない
360デフォルトの名無しさん:2010/12/09(木) 18:50:05
>>359 は将来、過去を振り返って、いろんな意味で恥ずかしく思うんだろうなぁ
361デフォルトの名無しさん:2010/12/09(木) 23:02:36
金言と間違えてないか。
362359:2010/12/10(金) 05:30:23
>>360
一時の恥で済ませてくれて感謝している
363デフォルトの名無しさん:2010/12/10(金) 22:28:09
いつのまにか Haskell.org のサイトが刷新されてた
364デフォルトの名無しさん:2010/12/11(土) 14:17:44
金言というより格言かもしれんが、Haskell でプログラムする上で
私が心に留めているのは次の言葉。

「時間を空間に」

自分でこれに気づいた時は「俺すげー」と革命が起きた感じだった。
後で調べてみると、誰もが当たり前のように考えた事だと分かったが、
これが Haskell の本質だと確信を得た感じで逆に嬉しかったな。
365デフォルトの名無しさん:2010/12/11(土) 21:40:14
kwsk
366デフォルトの名無しさん:2010/12/11(土) 22:11:27
>>365
たとえば、2つの計算 A と B が有るとする。
A を計算し、その結果が x だったらそれを使用し、
もし結果が y だったら B の計算結果を使用したい。

他の言語なら、A の後で B を計算する様に、逐次的に見える様に記述するが、
Haskell なら A と B を同時に計算する様に、宣言的に見える様に記述する。
それはリストに羅列されていたり、演算子で結合されていたりと、形は様々だ。
で、A と B のどちらが必要になるかはたいてい別のところに記述する。
B が不要なら実際には計算されない。

つまり、時間的な流れに沿った計算を空間に広げて「一望できる」ようにする。
これが遅延評価の為せる業であり、宣言的に記述できる Haskell の特徴だ。

これは一例だが、時間の流れを空間の広がりに換える考え方は、
Haskell プログラムの至る所で役に立つ。
367デフォルトの名無しさん:2010/12/11(土) 23:02:51
Algorithm = logic + control
368デフォルトの名無しさん:2010/12/11(土) 23:04:04
>>366
逐次的に見えるっていうか現実に逐次的だよね。
現実に沿った計算を、非現実的観点で一望することにどういう意味があるの?
369デフォルトの名無しさん:2010/12/11(土) 23:31:34
>>368
> 逐次的に見えるっていうか現実に逐次的だよね。

ちょっと違う。
現実のものを逐次的視点で捉えるか全体を一度に捉えるかの違いであり、
どちらが分かりやすいかは時と場合と「好み」による。
Haskell は後者の様に捉えた方が分かりやすい問題を綺麗に記述できる。

また、「一見」前者の様に捉えた方が分かりやすかった問題を、
後者の様に捉え直すことで、Haskell で扱いやすくする。

> 現実に沿った計算を、非現実的観点で一望することにどういう意味があるの?

計算Aはどのようにするのか、ではなく、計算Aとは何か、
という構造が分かりやすく(見やすく)なる。
(繰り返すが、後者の方を好む人にとって分りやすくなる)

例えばパーサーなら、X := A | B というバッカス記法をそのまま記述できる。
Aを読み取って失敗したらBを読み取ったものがXだと逐次的に捉えるのと、
XはAまたはBだと全体を一度に捉える違いだが、後者の方が一望できて分かりやすい。

分割統治も全体を一度に捉えた方が比較的分りやすい例だと私は思う。
370デフォルトの名無しさん:2010/12/11(土) 23:32:30
わざわざ道具を使うために問題を変質させているようにしか見えないのだが
例が悪いのか?
371デフォルトの名無しさん:2010/12/11(土) 23:38:31
>>366
データフローや並列計算の話をしたら喜ばれそうだけど
Haskellの本質とやらはそっち方向にはなさそうだよ
372デフォルトの名無しさん:2010/12/11(土) 23:38:58
無限集合をわざわざ空間と時間の置換で説明するのか。素晴らしい金言だな。
373デフォルトの名無しさん:2010/12/12(日) 00:00:04
賛同者がいっぱいいると思ってたんだが、なんかずいぶん否定的だな。
私も Haskell 歴はまだ1年とちょっとでかなり浅いから、
みんなを黙らせる良い例を挙げられないのが悔しいが・・・

時間と空間という言い方がまずかったのかな。
相対論的な意味での時間と空間の置換という意味では決してないんだ。

ではこう言ってはどうだ?
「動を静に」

手続き型言語なら時間軸に並べられた計算を動的に捉えて書くけど、
Haskell ならそれらの関係性を静的に一度に捉えた方が扱いやすくないか?
FRP による GUI ライブラリなんか正にそんな感じに捉えてるような気がするんだが。
374デフォルトの名無しさん:2010/12/12(日) 00:04:48
>「動を静に」
それなら良く分かる
手続き的か宣言的か、という奴だね
375デフォルトの名無しさん:2010/12/12(日) 00:06:38
>動を静に
これなら感覚としてはまあ分かる
でも金言って程ではないかな
376デフォルトの名無しさん:2010/12/12(日) 00:13:09
>>374
>>375
そうなのか

ただ、やっぱり私の中では時間的に考え方を空間的に捉え直す方が
しっくり来るというか、「動を静に」よりももう少し意味が広くて、
関数型の中でも遅延評価デフォの Haskell らしい感じが秘められてると思うんだが。
宣言的なら他の関数型でも普通にやってるし・・・

まぁいいや。
あまり盛り上がりそうな話でもなかったと言うことで、消えます
377デフォルトの名無しさん:2010/12/12(日) 00:37:37
>>373
それを、一言でいうと「数学と同じ」だと思うんだよね。だから、誰もわざわざ指摘しないというか。
378デフォルトの名無しさん:2010/12/12(日) 00:58:13
諸君、素晴らしい議論だ。
379デフォルトの名無しさん:2010/12/12(日) 01:02:52
>>377
なんでそういう大事なことを入門書では教えてくれないんだろうな。

入門するには頭を切り換える必要があると著者は分ってるはずだが、
何を頼りにどう切り替えるのか、本質は何かを解説しないで、
文法やケーススタディばかり解説する。
380デフォルトの名無しさん:2010/12/12(日) 01:25:15
数学は定常状態を仮定しますが、教育や計算は過渡現象だからです
381デフォルトの名無しさん:2010/12/12(日) 01:32:34
>>380>>379 に対するレスなのか?
いまいち意味が分らんな

教育と言えば、今の Haskell の入門書って、微分積分を使わずに
運動方程式の計算だけを教えて意味を教えない高校物理みたいな、
なんとも言えない気持ち悪さを感じる
382デフォルトの名無しさん:2010/12/12(日) 01:36:31
あんたら、どっから沸くんだYO
383デフォルトの名無しさん:2010/12/12(日) 01:42:21
>>382
こういう話が嫌なら、Haskell ブログラムのネタを振ってくれ

今は特に話題がないからダベってるだけだ
384デフォルトの名無しさん:2010/12/12(日) 01:49:03
前から思ってたけどこのスレ結構人いるよな
385デフォルトの名無しさん:2010/12/12(日) 01:58:08
>>383
STモナドは時間の流れを意識せずには書けないけれど、極めて純粋だよね
静なんだけど動なモナドだよね
この流れ的にはどうなの?
386デフォルトの名無しさん:2010/12/12(日) 02:06:16
>>385
俺が知るかよ

STモナドが気持ちいいかどうかと訊かれれば、俺は気持ちよくはないな
避けて通れるなら避けたいところだ

STモナドを使うと気持ちよく表現できるアルゴリズムとか未だ知らんし
なにかある?
387デフォルトの名無しさん:2010/12/12(日) 02:07:49
いくらでもあるだろ
クイックソートとかQR分解とか
388デフォルトの名無しさん:2010/12/12(日) 02:12:18
>>381 の続きだが

「虚数の情緒」みたいな、著者が可能な限り妥協しない、
分厚いが本質を丁寧に述べて Haskell の楽しさを思う存分語る、
そんな入門書があってもいいと思うな。
389デフォルトの名無しさん:2010/12/12(日) 03:03:46
"Arrows for Invertible Programming" という論文を読んでたら、
「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 内を探しましたが、見つけられないです。
390デフォルトの名無しさん:2010/12/12(日) 06:50:31
Haskellで、対話的なプログラムってどんな感じになりますか?
手続き的に書くと

1. 入力を促すメッセージを表示
2. キーボードから文字列を入力
3. 特定の文字列or文字列終端が入力されると終了
4. 入力された文字列に関数を適用
5. 適用した結果を表示
6. 最初に戻ってループ

な感じのプログラムなんですが…
391デフォルトの名無しさん:2010/12/12(日) 09:22:30
>>390
とりあえず書いてみた

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 ()
392391:2010/12/12(日) 10:14:29
sage忘れスマソ
仕様に完全には一致していなかったので書き直し:

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
393デフォルトの名無しさん:2010/12/12(日) 10:50:18
394デフォルトの名無しさん:2010/12/12(日) 11:51:47
どうすれば行頭にスペースを表示させられるのか、この迷える子羊にお教え下さい。
395デフォルトの名無しさん:2010/12/12(日) 11:58:42
>>366
上手く言えないけど、無駄に話を難しくしてる気がする。
「時間を空間」にの「空間」の意味が曖昧でよくわからない。

っていうかそれHaskellの本質ってより、ただ高階関数と条件分岐を
組み合わせただけなんじゃ...?
396395:2010/12/12(日) 12:05:04
>>381
プログラミングHaskellは高校物理っぽくないという点で
結構いいと思うんだけど、どうよ?

>>366
ちゃんと続き読んでなかった。動を静にか。それは結構納得できるかも。
397デフォルトの名無しさん:2010/12/12(日) 12:42:54
>>393
なるほど
「Proceedings of the 2000」や
「Proceedings of the 2000 ACM SIGPLAN Haskell Workshop」をキーワードに
ググってたから見つからなかったのですね。

ありがとうございます、助かりました。
398デフォルトの名無しさん:2010/12/12(日) 13:00:17
haskell版processing作ったけど需要ある?
399デフォルトの名無しさん:2010/12/12(日) 13:51:42
>>396
いいと思うよ
400デフォルトの名無しさん:2010/12/12(日) 14:27:00
>>395
> 「時間を空間」にの「空間」の意味が曖昧でよくわからない。

空間は、結果的にはソースコード上の横方向の広がりだ。
縦方向の広がりが時間と考えてくれていい。

たとえば2つの図形A、Bがあり、これらを表示するアプリを作るんだが、
デフォルトではAの座標はBの座標系で表現されている。
しかし、ユーザーのメニューでの選択などで逆の場合も起こる。
つまりBをAの座標系で表現した方が扱いやすくなる。

時間軸に沿うなら、初めはAをBにする座標変換行列を計算して保存しておき、
メニューを選択した時点でBをAにする座標変換行列を計算して置き換えると考える。

そうではなく、AとBの関係性をソースコード上で一望できるように
空間的(ソースコード上の横方向の広がりに換えて)に考えるなら、
初めからAからBへの座標変換行列とBからAへの座標変換行列の
両方を計算してタプルやリストなどに格納しておくような記述をする。

図形(座標系)が複数合っても同じ。
互いの変換行列を最初に計算して、関係性をグラフで表しておく。
後で必要になった時にグラフのノードを辿って行列をかけ算していく。

これでイメージが少しでも伝わらなかったら、たぶん私の考え方が
どこか間違ってると思うので、しばらく頭を冷やす。
401デフォルトの名無しさん:2010/12/12(日) 14:37:59
>>394
HTMLの実体参照。
つまり、「&nbsp;」を入れる。
402デフォルトの名無しさん:2010/12/12(日) 14:56:48
>>400
「時間を空間に」というと、破壊的に置き換えるイメージが伝わる
でも「時間だけでなく空間も」というと、両方を認めるマルチパラダイムになる
403デフォルトの名無しさん:2010/12/12(日) 15:01:41
数学者にマルチパラダイムを与えるのは、ボクサーから拳を奪うようなものだ
404395:2010/12/12(日) 15:04:45
>>400
ふーん。やっぱり何かおかしいと思うよ。わかりやすくするために例を挙げるのに、
座標変換やらなんやらが出てくるのか。

結果的にソースコードの横が空間で縦が時間だと言うけれど、
hoge >> huga

do hoge
   huga
が同じ意味になるという点についてはどうなんだろう。

しかも手続き言語でも、座標変換のルーチンは関数で定義するわけだから、
はじめから変換行列は(記述上では)計算済みということになるんじゃないの?

「動を静に」が納得できるのは、手続き言語では状態の変化の様子を
そのまま記述するのに対して、Haskellその他では、
ある状態が別の状態に変化するときの「間」を記述することが多いから。
状態そのものは「動」だけど、状態と状態の「間」は静だよね。
405395:2010/12/12(日) 15:38:39
>>400
>>369を読んでちょっと言いたいことがわかったかも。
モナドのことを言ってるんだな。そのパーサーの例だけど、パーサーは処理の観点から
見れば、逐次的なものだけど、文法を定義したい人間としては静的に捉えたい。

人間から見ると逐次的な部分は重要じゃないから、逐次的な部分をバインド演算子に中に
隠すことができるモナドはとても強力。

でも、それ捉え方の問題じゃなくて、言語の抽象化能力のことだと思う。
オブジェクト指向では文法の問題もあって、パーサーを静的っぽく記述するのは難しい。

少なくとも「時間を「空間に」」の言い方は全く良くない。「空間に」変えるのではなく、
時間的な問題を「隠蔽する」、と言う方が正しいと思った。
406デフォルトの名無しさん:2010/12/12(日) 17:33:47
手段が目的になっている奴ばっかりだなw
407デフォルトの名無しさん:2010/12/12(日) 17:54:57
それが研究ってもんだよ
408デフォルトの名無しさん:2010/12/12(日) 17:56:06
目的のために使える手段を選ぶんじゃない
手段を使えるようにするのが研究
409デフォルトの名無しさん:2010/12/12(日) 18:03:17
諸君、素晴らしい議論だ
410デフォルトの名無しさん:2010/12/12(日) 18:05:48
だが議論をするのが20年は遅かったな。
411デフォルトの名無しさん:2010/12/12(日) 21:26:38
>>398
ある。断じてある。
412デフォルトの名無しさん:2010/12/12(日) 23:56:16
>>398
欲しい!
413390:2010/12/13(月) 00:44:43
>>391-392
ありがとうございます。とりあえず対話的に動くところを確認しました。
やっぱり元があまりに手続き的だけに、若干ややこしくはなりそうですね。
あとは出てきた1つ1つの要素を見ていって、詳しく見ていこうと思います。
414Perl忍者 ◆M5ZWRnXOj6 :2010/12/13(月) 21:21:32
知的ぶってんじゃねえよ
ごみめら
415デフォルトの名無しさん:2010/12/13(月) 21:55:51
>>414
ちゅっちゅ
416デフォルトの名無しさん:2010/12/14(火) 00:21:55
>>413
> やっぱり元があまりに手続き的だけに、若干ややこしくはなりそうですね。

んー… 手続き的な処理は、例外的な処理を詰め込んでいくと、いっきにややこしくなる。
>>390の仕様だと、「3. 特定の文字列or文字列終端が入力されると終了」の部分。

こういうのは、自分が使うだけのプログラムなら、べつにわざわざ書く必要はなくって、終わればプロセスをKILLしちゃえば良い、例外がスローされたらそのまま死ねばよい、という考え方もできる。
そういうふうに割り切れば、プログラムはすごく単純になる。
でも、そういうときも綺麗にかっこよく終わりたいとなれば、面倒なことになる。

これは手続き型だろうと、関数型だろうと、どんな言語でも同じではなかろうか。
417390:2010/12/14(火) 00:58:39
>>416
あー、なるほど。
確かに例外処理含むとややこしくなりますね。納得です。
418デフォルトの名無しさん:2010/12/14(火) 08:27:17
ghci でコピペすると落ちる脆弱性
419デフォルトの名無しさん:2010/12/14(火) 13:36:21
>>418
xmonadもじゃない?
420デフォルトの名無しさん:2010/12/15(水) 11:59:16
ちょっとオレの妄想を聞いてくれ。

HaskellでFlash書けたら嬉しくね?
421デフォルトの名無しさん:2010/12/15(水) 12:13:04
Flashなんて将来消える技術だろう
422デフォルトの名無しさん:2010/12/15(水) 12:14:43
YHCのJavaScriptバックエンドとHTML5を組み合わせる方が近道じゃないか、良く知らんけど
423デフォルトの名無しさん:2010/12/15(水) 19:08:01
>>420
こういうことをやってる人もいる
http://hackage.haskell.org/package/swf-1.0.1
424420:2010/12/15(水) 20:41:56
>>421,422
スティーブ・ジョブズ乙
でも、たしかに、HTML5も魅力的。

>>423
やはり、オレが思いつく程度のことは、すでに手を付けている人がいるんだな。
425Perl忍者 ◆M5ZWRnXOj6 :2010/12/15(水) 22:40:21
ジーッ・・・

ここのスレよく脱線してますね
426デフォルトの名無しさん:2010/12/15(水) 22:44:02
人生を脱線してる奴に言われたくないわ
427Perl忍者 ◆M5ZWRnXOj6 :2010/12/15(水) 22:52:10
お前みたいなゴミよりまともだけどね

てめえみたいなやつは自殺しろ
428デフォルトの名無しさん:2010/12/15(水) 23:18:06
Haskell にほんの少しでも関係する話ができないのなら失せろ
429Perl忍者 ◆M5ZWRnXOj6 :2010/12/15(水) 23:34:26
クズ同士死んじまえ
430Perl忍者 ◆M5ZWRnXOj6 :2010/12/15(水) 23:36:38
おめえtsuwabukiぼうやかい?ww
* 名前 tsuwabuki
* 自己紹介 pi-calculus, CSP, lambda-calculus, haskell, erlang, HTML5, P2P, 料理作り(プリン・パンなど), 筍, 紅茶, サーバ運用, 自作サーバ, 電子書籍, iPhone, Android, Arduino, 変形合体ロボット, gumonji

http://twitter.com/iasija

かすみてえだな
420 426 428はtsuwabukiだろうね
てめえは低レベルだからさっさとしね
431Perl忍者 ◆M5ZWRnXOj6 :2010/12/15(水) 23:41:55
かわいそうだからここらへんにしといてやるか
ごみめら

ここのスレも荒れるしな
432デフォルトの名無しさん:2010/12/15(水) 23:50:50
正格評価をさせるもっとも基本的
な言語要素がseq a bなのはなぜ
なのでしょうか。force aがあって、
その場で、ただちにaを簡約するとなっ
いれば、seqよりも一般的と思う。
433デフォルトの名無しさん:2010/12/15(水) 23:56:13
force aとaは何が違うの?
434デフォルトの名無しさん:2010/12/16(木) 00:39:02
let x = 「複雑な式」
と書くと、xに束縛されるのは、
この式の評価結果(42という整数
としよう)ではなく、簡約グラフ
と呼ばれる一種の計算手順であると
入門者向けの説明ではなっている。
また、この式が42に簡約されるのは、
xまたはxを含む式をファイルに書き
だすときである。

結果、つまり、ファイルに42が書かれる
ことは間違いない。しかし、簡約グラフ
が蓄積されるかもしれない。そこで、
簡約グラフの形成後、ただちにこれを
42に簡約する指示を与える術がプログラマ
に与えることを考え、これにforceという
名前をつけたのである。

seq a bはこの弱いバージョンで、bよりもa
が先に簡約されることしか指示してない。
435デフォルトの名無しさん:2010/12/16(木) 01:31:05
>>432

その 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
と書いても同じこと。
436デフォルトの名無しさん:2010/12/16(木) 02:47:05
>>432
haskell普段あんま書いてないから文法的に怪しいが
もしそのforceがあったとしても
somefunc (force a) (force b)
がa→bの順に実行されるかは決まらない
(通常は遅延評価されるので文脈次第)
なので実行順序が決まらないその1引数のインタフェースでは役に立たない
437デフォルトの名無しさん:2010/12/16(木) 09:12:09
>>434
そういうことがしたいならseqで十分
let x = 式1 in 式2

let x = 式1 in seq x 式2
にすればいい
438デフォルトの名無しさん:2010/12/16(木) 09:57:52
439デフォルトの名無しさん:2010/12/16(木) 19:43:57
これって公式Haskell擬人化?
http://www.haskell.org/haskellwiki/Lambdabot
440デフォルトの名無しさん:2010/12/16(木) 20:01:15
>>439
かわいいね。実にかわいい。すごくかわいい。とってもかわいい。
441デフォルトの名無しさん:2010/12/16(木) 20:33:35
>>439
日本的な「萌え」にする必要はないと思うんだが、もう少しどうにかならなかったのかと小一時間…
442デフォルトの名無しさん:2010/12/16(木) 21:56:35
Geekそのものじゃねえか気持ち悪い
443デフォルトの名無しさん:2010/12/16(木) 22:21:17
普通にカートマン
444デフォルトの名無しさん:2010/12/16(木) 23:23:46
445デフォルトの名無しさん:2010/12/16(木) 23:26:15
>>436
無意識に左から評価すると考えてました。
そのためのseqなのですね。大変よくわかりました。
>>437
ありがとうございます。
表面的な使い方としては、理解できましたが、
seqでの等価表現のところがまだ理解しきれません。

>>442
geekはhaskellに似つかわしくないなぁ。
もっとクールビューティなのがいい。
446デフォルトの名無しさん:2010/12/16(木) 23:34:51
ギークっぽい言語って言えばperlだよね
447デフォルトの名無しさん:2010/12/17(金) 03:06:01
残念だ
すごく残念だ
448デフォルトの名無しさん:2010/12/17(金) 21:25:18
utf-8 の1文字の文字コードを utf-32 の 32ビット文字コードに変換したいので、
hackage にある 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)
449デフォルトの名無しさん:2010/12/18(土) 09:50:37
巨大な戦場ヶ原ひたぎさんみたいなのが良い
450デフォルトの名無しさん:2010/12/18(土) 10:11:06
>>448
それ多分mtl-2.0でStateモナドがStateT Identityの別名になったので壊れたんだな
encodingの作者に連絡して直してもらうべき
応急手当としてはencodingの.cabalファイルのmtlへの依存を<2.0に限定するとか
451デフォルトの名無しさん:2010/12/18(土) 10:19:37
しかしencodingってwindowsで使えるのか?
nl_langinfo呼んでるけど
452デフォルトの名無しさん:2010/12/18(土) 12:17:11
>>448 text か utf8-string 使った方がいいと思う
453デフォルトの名無しさん:2010/12/18(土) 14:07:47
>>450
State なんて自分で直接使うことは滅多にないので、
あれ? あったはずだがと思ってましたが、定義が変更されてたのですね。
拙い英語でバグレポートを出しておきました(ちゃんと伝わってるといいのですが)。

>>451
さぁ? 一応 cabal configure は通ったのでイケると思った矢先のエラーでした。

>>452
text ライブラリを使ってみたら、いともあっさりと目的が達成されました。
こちらでやることにします。

みなさん、ありがとうございました。
454デフォルトの名無しさん:2010/12/18(土) 14:17:15
455デフォルトの名無しさん:2010/12/18(土) 19:43:45
>>454
> ほらよ、童貞ども

純粋なのは良いことさ。
456デフォルトの名無しさん:2010/12/19(日) 02:10:34
hsc2hs の #enum の説明では
http://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 型は自動では変換されない?
457デフォルトの名無しさん:2010/12/19(日) 10:18:50
>>456
=で値を明示する形式だと変換しないよ(最初からHaskellでの名前だから変換する必要がない)
値を明示しない場合は、Cの識別子として値を取得した後に
Haskellの識別子として同じものを定義するので変換が必要

>あと、C 言語のヘッダに書かれてる enum 型は自動では変換されない?
それを(半自動で)やるのが#enum
例えば、
#include <stdio.h>
#enum CInt,, SEEK_CUR, SEEK_END, SEEK_SET
とすれば、seekCur, seekEnd, seekSetの三つが定義される
458デフォルトの名無しさん:2010/12/19(日) 11:22:40
>>457
ありがと、試したらできた。

あと、次のようにやると非常に分りにくいエラーが出ることも分った。

#{enum CInt,
  , AAA
  , BBB
  }

でも、この形であっても = を付けて値を明示すれば問題なく変換される。
こういう物だとして受け止めておくが、この仕様は訳分らん。
459デフォルトの名無しさん:2010/12/24(金) 12:49:40
イヴの日も堂々と議論しろよ
460デフォルトの名無しさん:2010/12/24(金) 13:02:39
みんなクリスマスにはマスコミに植え付けられたマニュアルどうりの行動をするよね。
できないやつは振りをするよね。
461デフォルトの名無しさん:2010/12/24(金) 16:43:53
そういうレベルのケンカは小学校まで
462デフォルトの名無しさん:2010/12/24(金) 19:16:45
では、イブらしく

魔法発動のプロセスが暗に Haskell プログラミングになっている
ファンタジーな物語を小説にしようかと思ってるんだが
463デフォルトの名無しさん:2010/12/24(金) 20:46:36
>>462
少女はマッチを一本すりました。
すると、なんと小さな炎の中にテーブルが現れたではありませんか。
「まぁ、なんておいしそうなご馳走!」
しかし、副作用はありませんでした。

少女はマッチを一本すりました。
すると、なんと小さな炎の中に優しそうな青年が現れたではありませんか。
「まぁ、なんておいしそうなイケメン!」
しかし、副作用はありませんでした、

少女はマッチを一本すりました。
すると、なんと小さな炎の中に大企業の人事担当が現れたではありませんか。
「まぁ、これでやっと就職口が!」
しかし、副作用はありませんでした。

イブの日の小さな贈り物でした。
464デフォルトの名無しさん:2010/12/24(金) 21:13:37
おお神よ、この憐れな少女に一握りのunsafePerformIOを与え給え
465462:2010/12/24(金) 21:20:19
お前の才能に嫉妬した

遅延評価も頼む
466デフォルトの名無しさん:2010/12/24(金) 21:43:59
スクルージが「どうして、いまさらこんな幻を見せるのだ」と尋ねると、
天使は同情の面持ちで「評価のときが来たのだ」と答えました。

スクルージは今までの自分を悔い、天使を見上げて問いかけました。
「私はやりなおすことができないのだろうか…?」

天使は同情の面持ちで「値を書き換えるのはバグのもとだ」と答えました。
467デフォルトの名無しさん:2010/12/24(金) 22:07:49
洋書の各トピックの最初に、こんな感じの意味深い単文が載るよね
468デフォルトの名無しさん:2010/12/24(金) 22:18:52
すみません
Shift-JIS を扱いたいんですけど、やっぱり無理ですよね?
掲示板でAAとか表示したいです
469デフォルトの名無しさん:2010/12/24(金) 22:37:41
>>468
Windows なら Win32API を使えばいい
他 OS は知らん
470デフォルトの名無しさん:2010/12/24(金) 22:48:02
試したことないがぐぐったらCodec.Text.Iconvとか出たけど、これはどう
471デフォルトの名無しさん:2010/12/25(土) 00:26:49
iconv使えば大半の文字コードへの変換が出来るよ。

でも最近のバージョンのghcだとそのままじゃビルドできなかったと思う。
例外周りが変わったせいらしい?
詳しくは覚えてないけどソース弄ってビルド通した記憶はある
472デフォルトの名無しさん:2010/12/25(土) 01:05:10
javaのtomcatみたいにHaskellで書かれたコンテナ探してるんだけど、オモチャみたいなヤツしかないですよね
tomcatもオモチャみたいだけど
apacheあたりと組み合せないとダメでしょうか
473デフォルトの名無しさん:2010/12/25(土) 01:16:51
>>472
最近 haskell.org のヘッドライン・ニュースにでてたSNAPが面白そう。
http://snapframework.com/
474デフォルトの名無しさん:2010/12/25(土) 08:35:06
パッケージインストールしようとsetupをghc --makeしようとしたら
ldが馬鹿にメモリ確保してフリーズ?する
Windows2000 SP4 CPU MMX Pentium 200MHz、 メモリ 96MBだから?
i586CPUでも動くんじゃないの?
475デフォルトの名無しさん:2010/12/25(土) 08:43:13
自分で解決できないやつがそんな古い環境使うのが問題
476デフォルトの名無しさん:2010/12/25(土) 11:57:26
1時間くらい放って置いたら出来てた

これはメモリが少ないせいかな
477デフォルトの名無しさん:2010/12/25(土) 12:01:10
これ10年前のスペックだろ
3万もしないネットブックの方が遥か上のスペックだぞ
478デフォルトの名無しさん:2010/12/25(土) 12:11:27
>>477
組み込みだと普通だと思うけど
Win2000を使ってるのはおかしいが
479デフォルトの名無しさん:2010/12/25(土) 12:13:45
10年前にはもうすでにペンティアム4-2GHzが発売されていたらしい。
480デフォルトの名無しさん:2010/12/25(土) 12:18:14
いま調べてたら、Haskell2010ってのがあるらしいけど、何これ?
481デフォルトの名無しさん:2010/12/25(土) 12:20:10
ぼくのかんがえたさいきょうのげんご
482デフォルトの名無しさん:2010/12/25(土) 12:21:31
Haskell 1.4 の次の Haskell 98 の次の仕様
483デフォルトの名無しさん:2010/12/25(土) 12:30:39
先週ダウンロードしたGHCはHaskell2010ですか?
484デフォルトの名無しさん:2010/12/25(土) 14:08:52
>>478
今時、組み込みでも300MHzていどは回さないとw
# まぁ、目糞鼻糞だが300MHzでx86-200MHzの倍程度のスピードはでる
485デフォルトの名無しさん:2010/12/25(土) 14:19:23
SuperHとかハイスペックだな
486デフォルトの名無しさん:2010/12/25(土) 16:01:49
リンクにバカほどメモリを喰うのって静的リンクしてることと関係あるの?
487デフォルトの名無しさん:2010/12/25(土) 16:45:47
いいえ。
488デフォルトの名無しさん:2010/12/25(土) 16:55:16
>>474 って、OSだけでメモリオーバーしてて、メモ帳起動してもフリーズすると思う
489デフォルトの名無しさん:2010/12/25(土) 20:46:22
Parsec の質問です。

C 言語のソースから、宣言されている構造体を抽出するパーサーを作りたいです。

"struct aaa {...} bbb" という形の構造体そのものを解釈するパーサーは作れました。
しかし、その C 言語のソースは構造体以外にも余計な文字列があるので、
それらを「解釈しないで」省き、構造体だけを抽出したいです。

そういう場合は、まず正規表現で構造体部分の文字列を取り出してから、
それらをパーサーで解釈するという方法はあまりに拙いでしょうか?

構造体を表す文字列に出会うまで全ての文字列を捨てる、
というパーサーがなかなか作れません。

ghc 6.12.3
parsec 3.1.0
490デフォルトの名無しさん:2010/12/25(土) 21:16:32
Cの型宣言部分は解釈しないと話にならんでしょ
関数本体とかは省略できるけど
プリプロセッサとかどうすんのかね
まあどうでもいいやねw
491デフォルトの名無しさん:2010/12/25(土) 21:18:12
>>488
しないしない
確かにOSだけで既にスワップ起こってるけど
自動優先度変更アプリ使って調整すれば
音楽聴きながらgvimでプログラミングできるよ
MinGWでコンパイルもできる
LibreOfficeも超モタツキながらも何とか動く

ghc --make でパッケージのSetupからexeファイル生成する時特有の現象なのです

あるいは小規模のmakeしかしてないから知らないだけか

多分既にスワップ起こしてるのにさらに
50MB程スワップ膨らませてるからだと思う
CPU使用率は20%くらいがずっと続くのにレスポンスは100%並にモタつく

これって処理の殆どがハードディスクとのI/O待ちって事でしょ?
492デフォルトの名無しさん:2010/12/25(土) 21:18:22
>>489
C言語のソースコードから自動でドキュメントを生成するツールがあるから、そのツールのソースコードを覗いてみればいいと思う。
493デフォルトの名無しさん:2010/12/25(土) 21:19:19
>>489
構造体を抜き出して何に使うの?
494デフォルトの名無しさん:2010/12/25(土) 21:24:48
>>491
コンパイルのときにガーベッジコレクションが頻発してるっていうオチか…
GHCもGHCでコンパイルしてるって話だったし
495デフォルトの名無しさん:2010/12/25(土) 21:26:57
>>493
>>489じゃないけど、構造体だけ抽出してスタブ作ってゲッターとかセッターとかの関数を自動生成したことならある
496489:2010/12/25(土) 22:17:13
>>493

>>495 と同じ知れない。
FreeType2 の Haskell ラッパーを作ろうとしてて、
構造体をデータ型で表現して Storable クラスのインスタンスにしたい。

正確には、hsc ファイル(の一部)を書くのを自動化して、
それで出力したコードを hsc2hs に入力する。

最初はライブラリ ドキュメントや C のヘッダーファイルを見て手作業でやってたが、
その構造体が比較的大きくて、量もそれなりにある。
ほとんど決まり切った形に変換していくのにイラついてきたから自動化させようと思って。

FreeType に限れば typedef struct AAA BBB; と typedef struct AAA {...} BBB;、
これだけ解釈できれば十分で、あとは手作業で楽に hsc ファイルが書ける。

本当は正規表現も使って本来の目的は達成できたんだが、
あまりにその場限りな感じの方法で、もっと洗練した方法があるか質問したかった。

>>492
探して見てみる、ありがと。
497デフォルトの名無しさん:2010/12/26(日) 08:40:37
そういう場合、他言語だとswig使う。
今みたら、haskell用は無い見たいだけど、作ると喜ばれると思う。
498デフォルトの名無しさん:2010/12/26(日) 12:26:13
>>497
それをするには、まず swig の仕組みから勉強しないといけないんだよなぁ
499デフォルトの名無しさん:2010/12/26(日) 12:29:27
language-cを使って、foreign importをヘッダーから自動で作るやつは作ったことがある
ただ、ASTがShowのインスタンスじゃないから、パースした後どういうデータ構造になるかチェックするのが大変だったけど
500デフォルトの名無しさん:2010/12/26(日) 12:38:08
というか、gccのソースを見ればいいんじゃね?
cのソースじゃなくてlexやyaccのソース
501489:2010/12/26(日) 14:01:37
>>500
いや、たがらね、#include とか 関数とかグローバル変数の宣言とか #define とか、
その辺りを解釈しないで無視するパーサーを作りたかったんですよ。

解釈するパーサーは以前 Parsec で作ったんですけど、
無視するパーサーというのはどうやって作るのかなと。
(頭が硬いのか、うまく作れない)

一応、無視する仕組みは Parsec 以外のものを使って実現はできました。

私に対するレスではなく一般論でしたらすいません。
502デフォルトの名無しさん:2010/12/26(日) 14:07:38
>>501
struct に遭遇するまでは全てのトークンを空白と同じとみなせばいいだけだと思うんだけど、そんなにめんどい話かな
503デフォルトの名無しさん:2010/12/26(日) 14:53:36
>>501
こんな感じ↓で構造体作るときはマクロを多用するもんだと思ってたよ

#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;
}
504489:2010/12/26(日) 15:03:11
>>502
それは

T := <改行空白含めて struct 以外の任意の文字列> "struct" <struct 本体>

という構文規則を表現するパーサーなのでしょうか。

それとも、"struct" 以外の "#define" や "void" などのキーワードもとりあえず認識し、
認識した結果として、空白と同じように何もしないというパーサーなのでしょうか。
505デフォルトの名無しさん:2010/12/26(日) 15:10:21
>>489
どの程度詳しいパースをやるかはお前が決めることだろ
Cに完全準拠したパースをやりたいなら、完全なCパーサ(language-cでも自作でも)を使って
コード全体を解析した上でstruct以外を捨てるしかない
とりあえず動けばいいというならregexでも何でも使えばいい
その中間も当然あり得る
506489:2010/12/26(日) 15:33:58
>>505
> コード全体を解析した上でstruct以外を捨てるしかない

「解析しない」というのを Parsec で表現可能なのか、
それとも解析した上で捨てるしか Parsec では方法がないのか、
どちらかを聞きたかったんです。

言葉足らずで苛つかせてしまって申し訳ありませんでした。

> コード全体を解析した上でstruct以外を捨てるしかない

わかりました。
507デフォルトの名無しさん:2010/12/26(日) 15:42:45
文脈から完全に切り離して解釈することは出来んからな。
単純なところを言えば、 struct が現れたところから解釈を始めるだけだと、コメント中や文字列中にあるものにもマッチしてしまう。
厳密にしようとすれば当然、完全な C パーサが必要。
508デフォルトの名無しさん:2010/12/26(日) 15:46:10
gcc -E でマクロ展開を出力したモノを解析対象にすれば #define とかの解析は必要なくなる
509デフォルトの名無しさん:2010/12/26(日) 15:49:04
>>507
Parsecで // 〜行末 と /* 〜 */ を以外を抽出すればいいだけじゃ…
510デフォルトの名無しさん:2010/12/26(日) 15:53:16
>>509
「単純なところ」と書いたのはわかりやすいから。
もちろん、簡単に解決できるところではあるけど、
例外ケースを全部洗い出すと C パーサになるよ。
511デフォルトの名無しさん:2010/12/26(日) 16:00:44
#if 0

ここをこめんととして使うなんてことはざらですよ

#endif
512デフォルトの名無しさん:2010/12/26(日) 16:12:03
>>511
それ、gcc -E で消えない?
513デフォルトの名無しさん:2010/12/28(火) 00:59:54
Haskell入門者です。

Haskellレベルで(IOでない)状態を扱うようなコードを書くときは積極的にStateモナドを
使うべきでしょうか。それとも引数をループで回すだけでよいでしょうか?

Stateモナドの使い方がパッと見ただけでは良く分からなかったので...。
514デフォルトの名無しさん:2010/12/28(火) 01:06:22
万能の解はない。
状況による。
515デフォルトの名無しさん:2010/12/28(火) 01:42:17
>>513
分かる方でやるべき。
後から修正が頻発するようなプログラミングをしてる場合にStateを使うべき。
ぱっと見でStateモナドが分かるならStateモナドを使えばいい。
516513:2010/12/28(火) 02:16:22
>>514
やはり使い分けですね。ありがとうございます。

>>515
> 後から修正が頻発するようなプログラミングをしてる場合にStateを使うべき。
おお、なんかリファクタリングっぽい。参考になります。
517デフォルトの名無しさん:2010/12/28(火) 23:15:48
え?
518デフォルトの名無しさん:2010/12/29(水) 01:19:48
え?
519デフォルトの名無しさん:2010/12/29(水) 01:40:40
んっ…
520デフォルトの名無しさん:2010/12/29(水) 01:58:11
ぴゅっ
521デフォルトの名無しさん:2010/12/29(水) 02:03:12
…ふぅ
522デフォルトの名無しさん:2010/12/29(水) 04:47:22
そういうネタしかないのはプログラマーとして考え物だな
523デフォルトの名無しさん:2010/12/29(水) 10:43:13
お前だってhogeとかhageとか変数名につけるだろ?
そういうことだ
524デフォルトの名無しさん:2010/12/29(水) 11:17:59
諸君、お勧めのパッケージは?
525Perl忍者 ◆M5ZWRnXOj6 :2010/12/29(水) 11:39:42
まだやってんの?グズどもは
さっさとスレ閉じて死んじまえよ

イワブキちゃん???
526Perl忍者 ◆M5ZWRnXOj6 :2010/12/29(水) 11:40:50
モナドモナド言いまくって逃げ惑うイワブキをつかんで
壁にガンガンたたきつられたら haskellやめそう(笑)
527デフォルトの名無しさん:2010/12/29(水) 11:42:17
>>524
hack
528デフォルトの名無しさん:2010/12/29(水) 22:25:29
wikipediaのラムダ計算のページ見てたら、ふと思い立ったので

funca x y = x * y
funcb a b = a * b

main = print (funca == funcb)

これやってみたらどうなるんだろうと思いつつ試してみたら普通に
No instance for (Eq (a -> a -> a))
って怒られてしまったんですが、
もしEqのインスタンスであるとしたら一応同じということが言えるんですよね?
529デフォルトの名無しさん:2010/12/29(水) 22:35:25
インスタンスにするときにメソッド == を然るべく定義すれば真にすることは可能であるが、そもそも「同じ」とは何であるかという話になるので初心者はそんなこと考えない方がいい。
530デフォルトの名無しさん:2010/12/29(水) 22:38:17
>>529
どうもです
そこらへんはあんまり深く追わないことにします。
531デフォルトの名無しさん:2010/12/29(水) 22:40:24
本末転倒だ。

同じという事が言えるように Eq のインスタンスを作れば、True となる。
532デフォルトの名無しさん:2010/12/29(水) 22:47:08
えー?そこは、
同じとは何であるかという話をしようよ
考えない方がいい、なんてよく言えたな
533デフォルトの名無しさん:2010/12/29(水) 22:48:15
>>531
例えばEqで「同じとは何か」を定義するときに

・ラムダ式の計算結果が同じになるか

・式の変数名まで同じであるか
のどちらを見るか次第では、TrueになるかFalseになるか変わる、という話になるんですかね
534デフォルトの名無しさん:2010/12/29(水) 22:50:46
Eqの定義しだい
535デフォルトの名無しさん:2010/12/29(水) 23:50:09
twitterのボットのリツイートがこわい
536デフォルトの名無しさん:2010/12/30(木) 01:30:04
>>528

いちおう、次の定義は動く。

{-# 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 の定義が優れたものかどうかは、オレは知らない。
537デフォルトの名無しさん:2010/12/31(金) 17:18:46
このスレマジで人すくねーよな。
前に釣りリンクここに書いてクリックした人数をカウントしたらたった23人だったよ
538デフォルトの名無しさん:2010/12/31(金) 17:26:43
23人もいることに驚き
539デフォルトの名無しさん:2010/12/31(金) 17:27:13
ソフトウェアはコピーできるから、人数は関係ない
それがソフトウェアの利点
540デフォルトの名無しさん:2010/12/31(金) 17:27:34
俺らたった23人しかいないなら勉強会ひらこうぜ
541デフォルトの名無しさん:2010/12/31(金) 17:27:58
いつも書いてるのは俺含めて3人ぐらいかなと思う
542デフォルトの名無しさん:2010/12/31(金) 17:32:44
このスレ開いてるやつ全員が釣りリンク踏むと思ってるとかゆとりか
543デフォルトの名無しさん:2010/12/31(金) 17:35:31
点呼とるか
544デフォルトの名無しさん:2010/12/31(金) 17:44:46
ID出ないスレで点呼って見たことないわ
545デフォルトの名無しさん:2010/12/31(金) 17:57:55
つ 節穴
546デフォルトの名無しさん:2010/12/31(金) 18:00:08
初心者なので普段の会話についていけなくてほとんどレスしてませんが
一応、新レスある度に見てます
547デフォルトの名無しさん:2010/12/31(金) 19:13:40
レスの内容よりスレの状態が気になるアホは
まあ再帰定義なわけだが
548デフォルトの名無しさん:2010/12/31(金) 22:17:41
Perl忍者も23人の内の一人か?
549デフォルトの名無しさん:2010/12/31(金) 22:41:01
Perlすら出来ないと告白したPerl忍者は、そもそもマですらない
550デフォルトの名無しさん:2010/12/31(金) 22:50:16
おしりがかゆい
551デフォルトの名無しさん:2011/01/01(土) 08:05:20
>>549
できないのになんでそのコテ名乗ってんだよ
552デフォルトの名無しさん:2011/01/02(日) 22:13:45
一通り Haskell の考え方や使い方は分った(ツッコミゆるさん)。

で、小粒だがちゃんとしたアプリを作り上げてみたいんだが、
何かネタはないかね?
553デフォルトの名無しさん:2011/01/02(日) 22:18:51
unix の man cat を読んで全く同じ仕様のものをつくってみそ
554デフォルトの名無しさん:2011/01/02(日) 23:33:34
>>553
ごめん
Windows の GUI アプリで何かネタ頼む
555デフォルトの名無しさん:2011/01/02(日) 23:52:41
>>554
じゃあぷよぷよクローン
556デフォルトの名無しさん:2011/01/03(月) 00:16:10
>>555
なるほど、ちょうどいいかも

ちょっと作ってみるわ
ありがと
557デフォルトの名無しさん:2011/01/03(月) 11:24:29
なぜか遅延評価されて消えないぷよぷよ
558Perl忍者 ◆M5ZWRnXOj6 :2011/01/04(火) 00:16:37
(笑)
559デフォルトの名無しさん:2011/01/04(火) 00:19:57
Perl忍者ってHaskellわからない&勉強する気が無いのになんでこのスレにいんの?
560デフォルトの名無しさん:2011/01/04(火) 00:32:07
FRP が最初に提唱された論文ってこれ?

Functional Reactive Animation

それとも、FRP というのは以前から提唱されてて、
Haskell における FRP を意味論の点からしっかり形にしたのがこれなの?
561デフォルトの名無しさん:2011/01/04(火) 11:43:11
解決策を提唱する以前に、問題提起をしっかり形にしてほしい。
562デフォルトの名無しさん:2011/01/04(火) 12:21:14
>>561
何の話だ?
563デフォルトの名無しさん:2011/01/04(火) 13:11:22
アブストラクトナンセンスな問題解決の話
564Perl忍者 ◆M5ZWRnXOj6 :2011/01/04(火) 17:48:16
キキ
565デフォルトの名無しさん:2011/01/05(水) 17:09:24
Fran のソースコードどこかに落ちてない?

本家は reactive に継承されたからもう公開しないよって言ってる
566Perl忍者 ◆M5ZWRnXOj6 :2011/01/05(水) 21:23:41
あっそっすか
567デフォルトの名無しさん:2011/01/06(木) 11:53:47
Reactiveとか触ってる人いる?(´・ω・`)
568デフォルトの名無しさん:2011/01/06(木) 12:43:10
>>567
使ってるよ。
活用しているとは言えないけどね。
まだ、いろいろ実験して調べてるところ。

仕組みがいまいち分らん
569Perl忍者 ◆M5ZWRnXOj6 :2011/01/07(金) 20:05:51
俺って知的好奇心がすごいんだぜアピールいいから^^;
570デフォルトの名無しさん:2011/01/07(金) 21:31:34
全く理解出来ないのにこのスレに常駐しているPerl忍者さんの知的好奇心も
なかなかですね
571デフォルトの名無しさん:2011/01/10(月) 11:31:18
初心者のしつもんなんですが
なぜGHCをインストールするには
MINGWをインストールする必要があるんですか?
572デフォルトの名無しさん:2011/01/10(月) 12:06:41
>>571
え? Haskell Platform を使えば、MinGWがどうとか考える必要はなくない?
C:\Program Files\Haskell Platform\2010.2.0.0\mingw 以下に入っているような、コンパイラとだかリンカだとかを使うんだろう。
少なくとも、GHCの開発者がGHC専用のDLL用リンカを開発しているとか考えにくい。
573デフォルトの名無しさん:2011/01/10(月) 12:15:08
なるへそ
STOPの意味がやっと分かった。
ではMINGWをインストールしてhaskell Platformの代わりにしよう。
574デフォルトの名無しさん:2011/01/10(月) 13:05:42
>>573
悪いことは言わん、初心者なら素直に Haskell Platform を入れとけ。

GHC 以外にも Cabal や hsc2hs などのツールもまとめてインストールされる。
入門書とか Real World Haskell とか解説サイトなどは、
そういうツールが既に入ってることが前提で説明されることが多い。
575デフォルトの名無しさん:2011/01/10(月) 13:39:44
Haskore http://www.haskell.org/haskellwiki/Haskore ってのを入れて
MIDIファイルは作れるようになったんですが
こういうこと↓するには何をどうすればいいんでしょうか?
http://www.youtube.com/watch?v=eLS6GHXWMpA&feature=related
576デフォルトの名無しさん:2011/01/10(月) 14:23:01
>>575
よく分からないけど、それ、画面のキャプチャと音楽を動画編集ソフトでミックスしているだけなんじゃないの?
577デフォルトの名無しさん:2011/01/10(月) 16:07:15
>>575
Emacs のバッファ内に書かれた Haskell のソースコードをコンパイルして、
あるいはインタプリタで実行する Emacs Lisp を書けばいいだけだと思うが。
578デフォルトの名無しさん:2011/01/10(月) 16:26:26
>>576-577
レスありがとう
なんにせよ、GHCiには音を鳴らす機能はなくて、他のソフトなりが必要ってことですかね
579デフォルトの名無しさん:2011/01/10(月) 16:36:25
>>578
もしかして、haskore-realtime じゃないのか?
http://hackage.haskell.org/package/haskore-realtime

使ったことないから分らんが、
一時ファイルに midi を書き出すことなく、
リアルタイムに再生させるそうだ。

まぁ、音を鳴らすための外部ランタイムが必要そうだし、
まして UNIX 依存らしいが。

これを利用して、単に emacs 上でソースを保存したら則実行する
マイナーモードの lisp でも使ってるのかもね。
580576:2011/01/10(月) 19:13:34
ごめん。オレが勘違いしていた。
これ、コーディング中(あるいはコーディング直後自動的に)そのコードを実行しているみたいね。

すでに言われていることだけど、flymakeみたいなEmacs LISPを使っているんだと思う。
おわびにちょっと調べてみる。
581576: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パッケージをインストールすればそのまま使える。
582576: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))))

;; つづく
583576:2011/01/11(火) 09:29:58
(defun auto-run-haskell-on-change (beg end len)
  (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 のように編集すれば、編集ごとにコンパイルチェックをかけ、それが通れば実行される。
584575:2011/01/11(火) 12:10:13
>>576さん、どうもありがとうございましたm(__)m
なんとかがんばってみます
585デフォルトの名無しさん:2011/01/11(火) 13:13:45
FRPを使ってる人教えてたもれ・・・
・BehaviorとEventの相互変換ができるとあるんだけど(Flapjax)実装的にはBehaviorにChangedイベントのようなものがあってそれを受けて改めてイベントとして変わったことを発行するの?
・Behaviorってモナドなの?(モナドもよくわかってない)
・Behaviorは引数(時間など。なくても可)をもってPullして引っ張ってくる値、EventはPushされるものって理解だけどあってる?

C#やってF#で関数型学んだ奴なのでいろいろ間違ってそうなんだか聞けるのここぐらいだったので頼む・・・
586デフォルトの名無しさん:2011/01/11(火) 19:37:39
Haskell による FRP ではなく、FRP 全般の事を聞いてるのですか?
Flapjax は 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。
587デフォルトの名無しさん:2011/01/11(火) 22:05:35
>586
>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である値をそのまま代入してどういうふうに実際の動作に結びついているのが不明なんですが。コンパイラによる?
588デフォルトの名無しさん:2011/01/11(火) 22:33:52
587
> ReactiveではBehaviorの値が変わったときに自動的に別のものに更新が伝搬したりするんでしょうか?

Reactive における Behavior は、プログラマにとってはまさに
Time -> a という型の関数に見えるように実装されています。
(引数として「時間」を受け取り、何か適当な型の「値」を返す関数)

時間 t を受け取ったらどんな値 v を返そうかというのをプログラマが定義するのですが、
Reactive の Behavior 型の値にはこれ以上の役割・機能はありません。

伝搬の意味が今ひとつ掴みかねてますが、
刻々と時間が経過してある behavior 型の値 v が変化しているとき、
ある関数 f を v に適用するようにプログラムを組んでいれば、
結局のところ関数 f は時間によって変化する値を返すようになりますね。
こうやって「時間による変化を伝える」ことは当然できますし、
プログラマが明示的にそのようにプログラムしないと伝わりません。

伝搬というのはこういう意味の事でよかったですか?


Flapjax の Tutorial は今ざっと読んでますので、
Reactive の behavior との違いがあるのか、などは後ほどレスします。
589Perl忍者 ◆M5ZWRnXOj6 :2011/01/11(火) 22:52:36
ここに乗せてあるやつ全部コピペっていってください
590デフォルトの名無しさん:2011/01/11(火) 22:54:32
>>587
今 Flapjax の Tutorial をざっと読みましたが、
Behavior と Event の概念は Reactive のそれと全く同じ、
つまり FRP 提唱者が最初に提唱したものと同じですね。

> FlapjaxではBehaviorはEventを継承したようなものでEventでかつ、その時の値(時間を引数とする値を返す関数である場合を含む)を持つもののようです。

私はそのような感じを受けなかったのですが、
チュートリアルのどの辺りからそのように感じたのでしょうか?

Flapjax においても、Behavior と Event は
一方が他方を包含したり継承したりするようなものではなく、
全く別のものではないでしょうか。
Behavior は連続時間上の振る舞いを表す、
方や Event は離散時間上の出来事を離散ストリームで表す。

もしかして、Flapjax ライブラリ自体の実装の話でしょうか?
591デフォルトの名無しさん:2011/01/12(水) 00:03:15
>588,590
>伝搬の意味が今ひとつ掴みかねてますが、
イベントと同様に更新時にそれを参照しているものに何かの手段で伝わるかどうかという意味です。
アニメーションのように繰り返し評価されるため、更新されたことによる関連する値の再評価のタイミングなどを考えないものはいいと思いますが、表計算のようにグラフ的に更新が伝搬されるものが必要なモデルもあるのかと。

>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
592デフォルトの名無しさん:2011/01/12(水) 07:53:35
>>591
> アニメーションのように繰り返し評価されるため、更新されたことによる関連する値の再評価のタイミングなどを考えないものはいいと思いますが、表計算のようにグラフ的に更新が伝搬されるものが必要なモデルもあるのかと。

どうも伝搬の意味が分らない思ったら、私の方が遅延評価で考えていました。
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 をサンプリングして離散化します)
593デフォルトの名無しさん:2011/01/12(水) 09:41:43
あー、Haskellだと遅延になるからまた話が変わってくるのか・・・
が、Eventではその更新された値自体は遅延で引っ張ってくるにしても、更新された事自体は正格的に実行はされるんですよね?

いずれにしてもReactiveでのBehaviorとEventの扱いがスッキリしました。ありがとうございました。
自分の実装でBehaviorをどんなふうに実装するかちょっと考えてみます。更新があった時点で副作用させたい時もあるだろうからなんかしらのEvent的なBehaviorは作るのかな・・・

ちなみに
>例であがっているBehaviorである値をそのまま代入してどういうふうに実際の動作に結びついているのが不明なんですが。コンパイラによる?
これはFlapjaxではコンパイラがliftしたものに展開してくれてるそうです。コレも楽そうでいいですね。
594デフォルトの名無しさん:2011/01/12(水) 19:23:12
>>593
> 更新された事自体は正格的に実行はされるんですよね?

そもそも、更新という概念じゃないんです。
更新という概念自体、命令型言語特有のものなので。

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 に続く
595デフォルトの名無しさん:2011/01/12(水) 19:25:27
>>594 からの続き

一方 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 とは違いますね。
596デフォルトの名無しさん:2011/01/12(水) 20:35:37
>595
イベントもなんですか。
むーなんかそこまでいくと色々と非効率になりそうな・・・
だからEventの実装が時間と値のタプルになってるんですか。

まぁ実装方法はいろいろだろうしそこはあまり問題ではないんですが。

F#などではFlapjax的に実装したほうがよさげっぽいです。色々と。
597デフォルトの名無しさん:2011/01/12(水) 21:59:14
>>596
> だからEventの実装が時間と値のタプルになってるんですか。

いや、だから「実装」は全然違いますって。
>>594 でも、正確にはこのように解釈できるモノと言いました。

FRP 提唱者が提唱した Event の概念が「時間と値のタプルの無限リスト」であり、
ライブラリ利用者も Event 型の値の意味をそのように解釈できるということ。

reactive の論文(http://conal.net/papers/push-pull-frp/)や、
ソースコードを読めば分りますが、実装は「効率的に実行できるように」
けっこう複雑な仕組みになってます。


余計なお世話だとは思いますが、実装より先に、
「実のところ FRP って何?」という部分をしっかり押さえた方が、
結局のところ近道だと思います。

で、私も説明が下手なので、やはり最初に提唱された時の論文を読んだ方が
断然いいと思います。
598デフォルトの名無しさん:2011/01/12(水) 22:13:19
>>596
言い忘れていました。

数ある FRP の中でも reactive はどちらかと言うと
アニメーションを得意としているような感じです。
と言うのも、作者(FRP 提唱者)が昔から
Functional Reactive Animation に興味を持ち続けているので。

だから、reactive のシステムを GUI システムの構築に利用するには、
その上に一皮ラッパーを被せたり、reactive を改造する必要があります。

reactive の前身である Fran もアニメーション用で、
Fran を GUI に利用した FranTk というライブラリが別の人によって作られましたが、
やはり Fran をそのまま利用する事はできず改造したと論文で述べています。

なので
> F#などではFlapjax的に実装したほうがよさげっぽいです
言語によってはというよりは、活用目的によって実装を考えるべきですね。
599デフォルトの名無しさん:2011/01/13(木) 00:41:11
>597

すいません、自分は「概念」と「実装」の区別を場所によって明確に区別せず"実装"という言葉を使ってました。

>余計なお世話だとは思いますが、実装より先に、
>「実のところ FRP って何?」という部分をしっかり押さえた方が、
>結局のところ近道だと思います。

ここをしっかり押さえるのが正直難しいです・・・
ここ数日、いろいろ見て、で結局具体的にどういう事ができるの?というのを行ったり来たり。
ひとまずつくろうとしてるものに十分な感じにはつかめた気もしますが、もっと掘り下げると色々とエレガントにできそうな。

こちらもOCamlですがまた少し別の視点から実装してるようです。
http://ambassadortothecomputers.blogspot.com/2010/05/how-froc-works.html

>言語によってはというよりは、活用目的によって実装を考えるべきですね。
ですね。ひとまず必要な部分から手をつけていきます。
600デフォルトの名無しさん:2011/01/14(金) 22:30:54
http://bit.ly/f0cCUo
によると、すでに(部分的に)GHCで書かれたアプリがApp Storeに並んでいるらしい
意外なところからHaskellが金になる可能性がでてきたな
601デフォルトの名無しさん:2011/01/14(金) 23:02:08
Android上で動いて欲しい
602デフォルトの名無しさん:2011/01/14(金) 23:24:06
MINIX上で・・・
603デフォルトの名無しさん:2011/01/15(土) 00:35:20
Haskellコードならけっこう簡単に Objective-C にトランスレートできるかもしれん
604デフォルトの名無しさん:2011/01/15(土) 08:28:57
手続き型言語にコンパイルしないと関数型言語は実行できないんじゃないですか?
それとも専用のコンピューターがあれば関数型言語のまま実行できたりするんですか?
手続き型言語と関数型言語は同列に並んでるけど、本当は上下関係じゃないですか?
605デフォルトの名無しさん:2011/01/15(土) 08:41:07
独自用語なら何でも言える
606デフォルトの名無しさん:2011/01/15(土) 13:17:58
>>604
機械語は関数型言語
607デフォルトの名無しさん:2011/01/15(土) 23:18:36
ParsecみたいなLLのパーサだと
左再帰やFirst/First、First/Followのコンフリクトが起きますよね
よくRFCとかにABNFが載っているけど、これをそのまま書き下すと
左再帰はchainlがあるとしても
First/FirstやFirst/Followのコンフリクトが起きます
こういうコンフリクトは手動でBNFを変形して解決されてるのでしょうか?
もしそうだとすると、実用レベルではLRパーサのほうがいいのかなとか
思うのですが、いかがでしょうか
今作っているプログラムで、そこでちょっと詰まったもので
608デフォルトの名無しさん:2011/01/16(日) 05:48:32
うむhappyとalexだな
609デフォルトの名無しさん:2011/01/16(日) 21:44:34
Parsecの質問です
parser = many1 letter `sepBy` delimiter
where delimiter = char ','
上はcharが区切りの場合ですが、
delimiter = string "hoge"ならmany1 letterの部分をどう書けばいいんでしょうか?
610デフォルトの名無しさん:2011/01/16(日) 22:12:58
>>609
何も変える必要ないよ
many1 letter のままでいい

なぜ何か変えないといけないと思った?
611デフォルトの名無しさん:2011/01/16(日) 22:23:19
>>610
many1 letter だとhogeにもマッチしてしまうためです
実際、結果もそのようになります
612デフォルトの名無しさん:2011/01/16(日) 22:40:42
>>611
あぁ、そういう事ね、確かに

以前やったような気がするから、ちょっと思い出してみる
613デフォルトの名無しさん:2011/01/16(日) 23:11:46
RWHを読んでるのですが、Stateモナドのありがたさがよく分かりません。
乱数以外のもっと簡単なStateの例題があったらおしえてください。
614デフォルトの名無しさん:2011/01/16(日) 23:41:46
よい例題と言うとちょっと思い浮かばないんだけど
逆に State を使わなかったとしたらと考えてみて。
状態を表す変数を受け渡さないといけないわけ。
その受け渡しを隠してくれるのが State モナド。
State に限らずモナドはそういった暗黙の受け渡しを担っていると言える。
もし今までにオブジェクト指向でのプログラミング経験があれば「カプセル化」が重要だということはよく知っていると思うけど、
モナドは Haskell においてカプセル化を実現するための機構と考えればいいと思う。
615デフォルトの名無しさん:2011/01/16(日) 23:43:49
>>613
圧縮展開で
スライド辞書をStateモナドで実装したことある
616デフォルトの名無しさん:2011/01/16(日) 23:58:24
・状態の「受け渡し」を表現してる
・Stateのコンストラクタの引数が関数
・>>= の右側の引数が Stateを返す関数

この3点が難しくてひっかかる
617デフォルトの名無しさん:2011/01/17(月) 00:26:03
>>611
昔のソースコードを漁ってやっと思い出した
sepBy は使ってなかった

結局これで一応できる

many (try (manyTill letter $ string "hoge") <|> many1 letter)

かなり不格好になってしまった、もっと洗練された書き方があると思う

また、"hogeABChogeEF" の結果が ["", "ABC", "EF"] となって、
sepBy とは微妙に挙動が違うので注意

「文字列 s の直前まで任意の文字列にマッチするパーサー until」が作れれば、
until s `sepby` string s でできると思う
昔のソースコードには試みた形跡があるけど、面倒になって諦めたみたい
618デフォルトの名無しさん:2011/01/17(月) 00:42:40
モナドをプログラマーの使い道的に見ると
コンティニュエーションの連鎖で次のものにいろいろ渡したり計算の前後でゴニョゴニョ処理を紛れ込ませられるって把握しとけば夜露死?
619609:2011/01/17(月) 00:52:06
>>617
manyTill letter (try $ string "hoge") <|> ..でいけました
結果はnot . nullでfilterして使うことにします
遅くまでありがとうございました
620デフォルトの名無しさん:2011/01/17(月) 02:19:42
わかりやすい
(a,s) -> (a,s)

汚い
a -> s -> (a,s)

マジキチ
a -> State s a
621デフォルトの名無しさん:2011/01/17(月) 08:14:23
>>609
>>617
解決できればなんでも良いけど、それ、もしかして字句解析と構文解析を分けるべきところではないだろうか。

>>613
GHCのコンパイラ機能・インタプリタ機能をライブラリとして使うAPIが、独自モナドだけど機能的にはStateモナド(+ IOモナド?)と同じものを使っているよ。
さっき話題になっているParsecも、やはり機能的にはStateモナドの一種。Stateモナドとして実装することもできただろう。
622デフォルトの名無しさん:2011/01/17(月) 10:53:49
haskellの文字の色が変わるエディターないですか?
623デフォルトの名無しさん:2011/01/17(月) 11:12:25
>>622
Emacs
624デフォルトの名無しさん:2011/01/17(月) 12:53:13
>>622

>>633 の他にも Editra や Yi も構文を解析して色を変えられる

構文を解析するほど機能的ではないが、
文の正規表現にマッチした所の色を変える程度でよければ、
(関数のシグネチャを定義する所とか、大文字で始まる識別子とか)
秀丸など他にもたくさんのエディタでできる
625624:2011/01/17(月) 12:54:40
すまん

>>633 の他にも

>>623 の他にも
626デフォルトの名無しさん:2011/01/17(月) 15:22:03
ghciがreadlineからhaskelineを採用するようになってから
履歴(↑、ctrl-p)の表示に時間が掛かることがたまにある
627デフォルトの名無しさん:2011/01/17(月) 18:00:51
>>626
うちは最新の Haskell Platform 入れてるけど、
ghci の履歴で待たされたと感じたことは一度もないな

履歴と言ってもせいぜい過去4、5件分さかのぼる程度だが

どのくらい時間掛かるの?
628デフォルトの名無しさん:2011/01/17(月) 18:23:34
>>627
数十秒
他の作業をしてghciに戻ってくるとよく発生する気がする
スワップアウトしてるのかな
629デフォルトの名無しさん:2011/01/17(月) 19:24:55
数十秒って冗談だろ、俺の自慰完了よりなげーよ

遅いのは履歴(↑、ctrl-p)の表示だけなの?
ロードとか、関数の評価とか、シェルコマンド実行とかはどうなのよ
そういうのは気にならんの?

再インストールした方がいいんじゃないかな
630デフォルトの名無しさん:2011/01/17(月) 19:37:52
>>629
遅いのは履歴だけだよ
それも一つ前の履歴を表示する時だけ
ていうか早漏すぎだろ
631デフォルトの名無しさん:2011/01/17(月) 19:43:22
他にhaskelineを使ってるプログラムって何があったっけ?
632デフォルトの名無しさん:2011/01/17(月) 20:49:31
とくに見当たらんな

haskeline で何か自作してみればいいんでないか
それでも数十秒も待たされるんなら、
そちらの PC と haskeline の相性が悪いんだろ

ちなみに、一度 ghci を :q で落としてから立ち上げ直すと、
しばらくは正常なのか?

それで実用上問題ないのなら、そういう使い方でも良いと思う
立ち上げ直しても、履歴は消えずに残ってるから
633デフォルトの名無しさん:2011/01/17(月) 20:55:46
確かに。自作すればいいんだな
サンクス

634デフォルトの名無しさん:2011/01/18(火) 01:59:15
haskelineはキーボードとの相性というオチの可能性があるから怖い
635デフォルトの名無しさん:2011/01/18(火) 05:19:40
ghciの履歴って、その度にファイルに書きこんでるんでしょうか?
だったら、後からコマンド一覧を見てコードの参考にしたいので、そのファイルの場所が知りたいです
636デフォルトの名無しさん:2011/01/18(火) 19:02:38
3行だけ処理ってのをもっとすっきり書けないでしょうか

main=do cs <- getContents
threeline <- mapM return (take 3 $ lines cs)
mapM_ putStrLn threeline

自分の端末EOFがうまく入らなくて
設定するのもめんどくさくて
637デフォルトの名無しさん:2011/01/18(火) 19:22:25
threeline <- mapM return (take 3 $ lines cs) は
let threeline = take 3 $ lines cs で良いと思う。
638デフォルトの名無しさん:2011/01/18(火) 19:56:55
ありがとうございます。
3行まとめて処理ではなくて
1行ごとに処理されて前より便利になって嬉しいんですが
これは何故なんでしょうか
639デフォルトの名無しさん:2011/01/18(火) 20:01:33

main = interact (unlines.id.(take 3).lines)

% main.ext < file.txt

640デフォルトの名無しさん:2011/01/18(火) 21:01:57
interactは便利ですね、ありがとうございます。
--run :: (CharParser () String) -> String -> String

myrepl f n = interact (unlines . (map f) . (take n) . lines)
main = myrepl (run p) 3
641デフォルトの名無しさん:2011/01/18(火) 21:26:03
>>638
getContentsは遅延IOだから所望する分だけ入力してくれるけど、mapMをかますことで一枚岩のIOとなるため。
遅延IOを操りたければ、System.IO.UnsafeのunsafeInterleaveIOを調べるべし
642デフォルトの名無しさん:2011/01/19(水) 20:19:42
以前ブラックボックスだったところが少し理解できました
myrepl f n = g >>= putStr . (unlines . (map f) . (take n) . lines)
where
g=unsafeInterleaveIO $ liftM2 (:) getChar g
main = myrepl id 3
643デフォルトの名無しさん:2011/01/19(水) 20:49:16
Parsecの質問です(2系)
εを含む文法に対するパーサ(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');
644デフォルトの名無しさん:2011/01/19(水) 21:08:12
>>643
根本的な解決になってるか知らんが、
<|> の右辺と左辺を逆にしたらいかんの?

(string "-" <|> (option "" (string "+"))) >> string "1"

つまり、εを含む文法を OR の一番最後で判定する
645デフォルトの名無しさん:2011/01/19(水) 21:31:05
>>644
わかる範囲では、基本的に指摘して頂いたような感じで解決しているのですが、
ただ、複数のεを含む非終端記号が<|>でつながれていたり、
修正がその非終端記号だけでは済まなさそうなものも多くて
手作業で修正するのは絶望的です(正しく動くか検証出来る気がしないです)
出来れば元のBNFは修正せずに何とかならないでしょうか
646デフォルトの名無しさん:2011/01/19(水) 22:01:08
>>645
他の構文解析器のことは知らんが、Parsec の run 系関数は、
入力されたパーサーが文法的にεを含んでいるかどうかを全く把握しない
(そもそも、各パーサーがεを含んでいる事を外部に知らせる術がない)

> 出来れば元のBNFは修正せずに何とかならないでしょうか

残念だが、現時点のバージョンの Parsec では何ともならんと思うぞ

> 手作業で修正するのは絶望的です

これは、Parsec で作った自分のパーサーを見て、
これは εを含んでいる、これは含んでいないと見分ける方法、
つまりアルゴリズムは持っているが、手作業では面倒だという意味か?

もしそのような意味であればラッキーだ
そのパーサーのプログラム文を解析し、
<|> の各項を適切な順に並べて出力するパーサーを作ればいい

その方法がない、あるいはそれも面倒なら、絶望的だな
647デフォルトの名無しさん:2011/01/19(水) 22:31:53
後者ですね、残念
A = Be | Ce | De | F
Be = B*
Ce = C?
De = D >> string "" --この種もε?
これを書き換えるとすると
A = B' | C | D | e
B' = B+
最も外側にある<|>までさかのぼってこの種の変換をする
再帰関数を書くことでうまくいくかもしれないけど
正しく動くのか検証出来そうにないです
Maybe C -> C
みたいにパース結果の型も変わるだろうし

色々と調べてみて
RFCにあるようなBNFをそのまま記述するだけで何とかなる、
みたいな夢のパーサジェネレータはないのかなと思いました
そういうのを実現出来るものがあるとすれば
GLRみたいなアルゴリズムを実装するしかないんでしょうね
そうすると実用的な速度では動かないから
実用レベルでは、もうちょっと細かいハックが色々と要るってことなのかな
648デフォルトの名無しさん:2011/01/19(水) 23:24:53
>>674
Parsec や Haskell の勉強ではなく、純粋にある文を構文解析した結果を
Haskell で処理するのが目的なら、うまくいくという bison を
中間処理モジュールとして使えばいいのでは?

あるいは、LR 文法を解析する Haskell コードを生成する Happy を使うとか
これも yacc や bison などと同くコンパイラ コンパイラのひとつ
GHC で使われている実績もあって、コンビネータの組み合わせで表現する
Parsec などのパーサーより速いそうだ

ちらっと見たところ、ソースも yacc などとほとんど同じだ
(使ったこと無いから、あとは自分で調べてくれ)
649デフォルトの名無しさん:2011/01/19(水) 23:35:38
はぁ・・・
またレス番間違えた

>>648>>647 宛だ、すまん

今 Happy のユーザーガイドをざっと眺めてたら、
GLR パーサーが作れるみたいだな
(つまり、GLR アルゴリズムを使って構文解析する Haskell コードが生成される)
650デフォルトの名無しさん:2011/01/20(木) 00:01:07
>>649さん色々とありがとうございます。
GLRが解析出来るっていいですね
parsecを知るとbisonはちょっと使う気になれないので
happy調べてみます

マスコットがわりと癒し系
このぐらいの可愛さだと安心。>>439・・
651デフォルトの名無しさん:2011/01/20(木) 00:47:10
sepByのセパレーターやmanyTillの〜までのパーサは同じような用途なのに
どうしてmanyTillの方だけtry必須なんですか?
652デフォルトの名無しさん:2011/01/20(木) 01:43:20
すみません。
Data.IORef って、値の再代入をしてるんでしょうか?
それとも、内部では再代入をしないトリッキーな方法で、再代入の機能を実現しているのでしょうか?
653デフォルトの名無しさん:2011/01/20(木) 07:52:22
>>651
べつに必須というわけじゃない
必須なんてライブラリ ドキュメントのどこにも書いてないだろ?

次の2つのパーサーのパース結果を色んな文字列で比べてみればいい

manyTill (string "abc") (string "abd")
manyTill (string "abc") (try $ string "abd")

ちなみに、Parsec のソースの Combinator.hs を見てみれば、
この場合になんで try がいるのかすぐに分る

意外にシンプルに書かれたソースなんで、
ついでに他の関数の中身も見てみるといいよ
654デフォルトの名無しさん:2011/01/20(木) 10:42:01
ParsecつかうのとANTLRとか使うのどっちが楽?
655デフォルトの名無しさん:2011/01/20(木) 12:43:14
「楽」の意味が分らん
具体的に聞け
656デフォルトの名無しさん:2011/01/20(木) 14:38:14
独自の文法作って、それを解析したものに応じた処理をかくとして、デバッグのしやすさを含めた開発生産性。
657デフォルトの名無しさん:2011/01/20(木) 18:08:30
Parsec の方が、解析と、解析結果を使うのと両方が同じ言語で一体となってて、
プログラムしやすいしデバッグもし易い。
なにより Haskell が使いやすい言語だし。

あくまで、Haskell に慣れ親しんだ者のごく主観的な「楽」です。
658651:2011/01/20(木) 21:04:14
>>653
色々試してみたけど、try抜きでは有用な使い道は無いと思うんですが
659デフォルトの名無しさん:2011/01/20(木) 21:28:37
>>658
> try抜きでは有用な使い道は無いと思うんですが

それは分るが、言いたかったのは
「manyTill だから必須なのではない」ということだよ

Aをパースして失敗したらBをパースする
という仕組みの「全ての」パーサーにおいて、
Aを途中までパースしかけたけど無かったことにしたい場合に、
try が必要になるだけのこと

manyTill がその仕組みになっていることは、
使い方やドキュメントから何となく分ると思うが、
ソースを見た方がよりはっきりするからソースの読解を奨めてる

関数の中で try を使っているかもしれないし、
プログラマに明示的に try を使ってもらうタイプのものかもしれない
そういう意味でも、やはりソースを見た方がいい

なぜ manyTill では try が要るのと考えていると、
他の提供パーサー、自作パーサーで同じような問題にぶつかり、
解決できなくてまた同じ質問することになりかねない
660デフォルトの名無しさん:2011/01/21(金) 23:14:11
OpenGLでビューアを作ってコンパイルしたらサイズが7MBになったんですけど、こんなにexeファイルって大きくなるんでしょうか?
C言語で作った同様のソフトは300KBでした。
661デフォルトの名無しさん:2011/01/22(土) 02:14:34
>>660
この辺は試した?
http://www.kotha.net/ghcguide_ja/latest/sooner-faster-quicker.html

どうしてもCよりは大きくなるとは思うけど。
662デフォルトの名無しさん:2011/01/22(土) 02:18:04
ソースコードを渡さずに、モジュールを配る方法を知りたいです

モジュールをオブジェクトファイルみたいに中身がテキストじゃないファイルに変換した後、モジュールのソースファイルを一切参照せずに、そのモジュールをimportしてコンパイルまでする方法ってないですかね

663デフォルトの名無しさん:2011/01/22(土) 02:19:59
↑ちなみにソースが汚いので見せたくないからです
664デフォルトの名無しさん:2011/01/22(土) 02:22:11
>>662
.oファイルと.hiファイルを配布すればできるんじゃね?
オレはためしたことないけど。
665デフォルトの名無しさん:2011/01/22(土) 02:36:10
Module.hs ... モジュールのソース
test.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に附属する他のモジュール

でできた
666デフォルトの名無しさん:2011/01/22(土) 02:39:10
ghc -c でできるのは Module.hi と Module.o だ…
667デフォルトの名無しさん:2011/01/22(土) 06:11:41
.oと.hiファイルだけを配布する場合、OSとアーキテクチャに加えて
GHCのバージョンが配布元と一致してないと使えないのでかなり不親切
READMEに「ソースは読まないで下さい。読んだら呪う」とか書いとくのが良いと思う
668デフォルトの名無しさん:2011/01/22(土) 10:50:57
>>667
じゃ、静的リンクではどうだろう?
Wiinows環境で静的リンクってできたかよく知らんし、GPLやLGPLのライブラリと静的リンクして、オブジェクトだけ配布するのはライセンス違反だけどね。
669デフォルトの名無しさん:2011/01/22(土) 11:27:02
ソースは読んでほしくないけど、「こんなのできた」って自慢したい
いったいどうすれば…
670デフォルトの名無しさん:2011/01/26(水) 12:46:52
ソースをモザイクを掛けて動画でみせつける
671デフォルトの名無しさん:2011/01/26(水) 13:14:11
これがホントの難読化
672デフォルトの名無しさん:2011/01/26(水) 13:42:22
C言語は納品するときに、ソフトで空白や改行やコメントを抜いたり入れたりして、わざとスパゲッティコードにしてる
Haskellだとそれができないから困る
673デフォルトの名無しさん:2011/01/26(水) 13:44:40
コメント欄に、グロAA
674デフォルトの名無しさん:2011/01/26(水) 15:14:58
AAでグロってなかなか難しいな
675デフォルトの名無しさん:2011/01/26(水) 15:37:26
>>672
{ ; } でインデント依存をなくせばいいじゃない
676デフォルトの名無しさん:2011/01/26(水) 15:49:55
>>675
空白タブと{ ; }は単純に置換できないから、自動化は頭使うと思う
677デフォルトの名無しさん:2011/01/26(水) 16:47:16
>>672
空白や改行を増やしたり減らしたりしても、自動整形ソフトがあるから意味ないような。
678デフォルトの名無しさん:2011/01/26(水) 18:02:13
高階関数を使いまくって難読化できないかな

ソースは凄く見難くなるけど、Stream Fusion などの仕組みで
コンパイル後は結局普通のソースと同じ働きをするコードを吐くみたいな
679デフォルトの名無しさん:2011/01/26(水) 18:19:26
GHCなら構文糖を全部展開した中間コード生成できた気がする。
それ使えば難読化も可能じゃないかな
680デフォルトの名無しさん:2011/01/26(水) 20:26:42
ghc -ddump-ds するべし
681デフォルトの名無しさん:2011/01/26(水) 21:18:31
Haskellはもっとモナドの操作を意識した構文を採用してほしい

ifM then else、caseM .. ofみたいな構文を入れてくれれば
caseの前に<-で一行増えるなんて悩みが無くなるのに
ifM :: (Monad m) => m Bool -> m a -> m a -> m a
だと今度は括弧がうざい
682デフォルトの名無しさん:2011/01/26(水) 21:22:46
1行増えることがどれほどあなたを悩ませてるのか、想像できん
683デフォルトの名無しさん:2011/01/26(水) 21:24:50
http://hackage.haskell.org/trac/ghc/ticket/4359
ここで提案されてる\case構文が入れば、

condition >>= \case
  True -> foo
  False -> bar

みたいに書けるね
684デフォルトの名無しさん:2011/01/26(水) 21:50:25
最近halpをemacsに導入してみたが悪くない。
https://github.com/darius/halp/
python2.xが要るけど、<M>-iでコメント行の式を評価してくれる。
--- 1+2
--- putStrLn "Hello"
とか書いといて<M>-iで評価すると
--- 1+2
-- | 3
--- putStrLn "Hello"
-- | hello
とかしてくれるし、ghciの機能である:tとか:iも打てる。エラーメッセージが出ないのだけが難点か。
685デフォルトの名無しさん:2011/01/28(金) 10:59:11
モナー化
686デフォルトの名無しさん:2011/01/28(金) 22:15:01
mf criteria operator list = filter criteria (map operator list)
これをポイントフリー化しろっていう練習問題(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 と続いていくという意味)
687デフォルトの名無しさん:2011/01/28(金) 22:42:38
自己レス。間違ってました
688デフォルトの名無しさん:2011/01/28(金) 23:22:05
>>681
計算の組み立てをするという問題について、モナドは解のひとつだけど、最適解ではない
という話を聞いた

それが本当なら、モナド特化の構文はもうちょっと様子を見た方がいいと思う
689デフォルトの名無しさん:2011/01/29(土) 00:35:11
Arrow とかが人気でてるって聞いたけど
690デフォルトの名無しさん:2011/01/29(土) 01:34:01
だれかモナドとArrowを分かりやすく説明してくれ・・・
691デフォルトの名無しさん:2011/01/29(土) 02:37:06
>>690
世界で一番か二番くらいにやさしい「モナド入門」
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
692デフォルトの名無しさん:2011/01/29(土) 04:46:15
>>690
Monadは、説明を聞くよりもStateモナドとListモナドを自分で再実装していじくりまわすのがお勧め。
693デフォルトの名無しさん:2011/01/29(土) 05:34:40
MonadよりComonadの解説が聞きたい
694デフォルトの名無しさん:2011/01/29(土) 08:35:46
余モナドって使えるもの?
695デフォルトの名無しさん:2011/01/29(土) 12:59:41
Arrowは.NETのRx的な感じなのかなー。数学的な位置づけとかは良く解らんが、使い方はわかった。
誰かがRxはモナドなのかとか言ってたがそれにはうまく答えられんがw
696デフォルトの名無しさん:2011/01/29(土) 13:00:33
>>690
アローの自分の理解
 受け取り:関数
 返すもの:(関数の引数の型)と(関数の戻り値の型)を入れた箱

アロー同士をくっつけて、関数を色んなやり方で合成出来る
関数A:文字列(テーブル名) -> 数値(主キー)を
関数B:数値(主キー) -> 文字列(名前)
関数C:数値(主キー) -> 性別(名前)
この3つに対応するアローを作って適切な順序で合成すると、
テーブル名を入力して、(文字列,性別)の組を返す関数が作れる
697デフォルトの名無しさん:2011/01/29(土) 13:39:43
>>696
わざわざアローを使う意義がわからんなぁ
それなら、普通に関数の合成でよくない?

アローによって抽象化された概念が、
関数の合成「以外」にも応用できないと、
抽象化の意味があまりないような気がする

アローによって抽象化された概念とやらが
一体何なのか未だによく分らんが
698デフォルトの名無しさん:2011/01/29(土) 14:17:35
>>697
そうかもしれない
699デフォルトの名無しさん:2011/01/29(土) 17:47:37
gtk2hsってメインのhttp://haskell.org/gtk2hs/が消えて久しいけど
どうなってるのこれ
gtk2hsは0.10.1までで、cabal対応のgtk-0.11.2以降を使えってことなのかな
700デフォルトの名無しさん:2011/01/29(土) 18:11:02
>>690
3分で解る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
副作用がある特別な値を抽象化したのがモナドで、
副作用がある特別な関数を抽象化したのがアローですよね。
普通の関数合成はアロー合成の代わりにならないのでは?
701デフォルトの名無しさん:2011/01/29(土) 18:44:16
Arrowって魅力的な実例が少ないんだよな
正確に言うと、MonadにはならないがArrowになる実例
パーサもFRPもXML処理もMonadになることが多そうだし
702デフォルトの名無しさん:2011/01/29(土) 19:23:15
>>700
> 副作用がある特別な関数を抽象化したのがアローですよね

そうなの?

「計算」という概念を抽象化して圏論の視点で構築したのがアローじゃないの?
モナドも「計算」という視点で捉え直せば Kleisli というアローで一般化できるのだと

アロー自体に副作用の概念は特にないと思ってたのだが
703700:2011/01/29(土) 20:29:53
>>702
正しくは「抽象化した」でなく「抽象化できる」ですね。
確かにアロー自体には副作用の概念はなく
副作用があろうがなかろうがアローにできます。

実際にアローを使うのは普通の関数では書けない時だから
その時はアロー合成を関数合成に置き換えられないという話です。
704デフォルトの名無しさん:2011/01/29(土) 20:43:46
副作用の話はとりあえず置いておいて

確認なんだけど、結局同じ引数に適用したら同じ値に還元されるという意味において、
モナドは 100% アローで表現可能だし、アローは 100% モナドで表現可能だよな?

もしかして違うか?

違ってたら完全に私の認識が間違ってるっぽいから、
もう一度ちゃんと勉強し直したい
705デフォルトの名無しさん:2011/01/30(日) 01:12:31
>>704
> アローは 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を定義できるか、ということになる。
706705:2011/01/30(日) 01:25:17
オレがこの間まで試していたものが、実際にこのappを定義できないArrowだった。

data 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)

が同じ意味になるように定義することはできない。少なくともオレがモデル化しようとしていた回路の世界では。
上の例だと、その回路には最初からカウントアップする回路部品が含まれており、回路全体が繰り返し計算されることによってカウントアップされていく。
しかし、下の例だと、回路全体を計算するたびに新たにカウントアップ部品が生成されてしまうので、意味がない。
手前味噌かつ簡潔すぎて分かりにくいと思うが、まぁ、モナドに出来ない具体例は意外と簡単に見つかるよ、という話。
707デフォルトの名無しさん:2011/01/30(日) 01:43:04
デカルト圏とカルテシアン閉圏って同じなの?
708705:2011/01/30(日) 02:01:13
ごめん。
> たぶんデカルト圏かならずしもモナドならず、ということだと思う。

というのは、分かっていないのにディレッタンティズムに駆られて余計なことを書いた。
これは取り消す。
709デフォルトの名無しさん:2011/01/30(日) 02:24:53
あかん、本質的に Arrow とは何かを学び直さないと

論文漁ってくる
710デフォルトの名無しさん:2011/01/30(日) 08:05:22
ここまでの流れ、「Monad/Arrowがよく分からねえ!!」という人は
自分だけじゃないらしいので、少し安心した。

自分の中では「結合子(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は難しいと思う。
711デフォルトの名無しさん:2011/01/30(日) 08:37:32
というかざっくり言っちゃうと、
モナドは(a -> M b)が結合できるもので、アローは(A a b c)が結合できるもの、それにいろいろ理屈を付けただけでしょ。
モナドは結合する単位が(a -> M b)という関数の形に限定されるから、アローより限定的なものしか表現できない。
それでいいんじゃないの?
712デフォルトの名無しさん:2011/01/30(日) 09:14:13
>>710
その見方は大袈裟すぎ

パーサコンビネータのライブラリを良く見てみると、モナドとしての要件「も」満たしていることが分かった
→せっかくだからMonadのインスタンスにしようぜ
→do記法やらmapM_やらがタダで使えてハッピー

というだけ

別にコンビネータライブラリを書くときにMonadやArrowインスタンスを与えなきゃならんという決まりはないし、
実際Text.PrettyPrint.HughesPJなんかはモナドでもアローでもない
713デフォルトの名無しさん:2011/01/30(日) 11:34:45
大学でドラムコホモロジーの勉強した(みたいな)んだけど、これ知ってると、Haskellのモナドを簡単に理解できますか?
714デフォルトの名無しさん:2011/01/30(日) 13:28:18
>>713
勉強したみたいなら、Haskellのモナドを簡単に理解でるか
自分で試してみればいいんじゃね?
715デフォルトの名無しさん:2011/01/30(日) 13:32:33
>>711
それでいい人もいれば、それではなんか気持ち悪い人もいる、それぞれだ

俺は後者、理屈が分らんと気持ち悪い

理屈というか、「(a -> M b)が結合できるもの」とか
「(A a b c)が結合できるもの」を抽象化できないと気持ち悪い
抽象化できると(抽象化の過程が理解できると)、
たいていは今まで隠れてた本質が見えてくる

その抽象化の道具として今のところ数学が役に立ってるけど、
別のもので綺麗に抽象化できるならそれでもいい
716デフォルトの名無しさん:2011/01/30(日) 13:45:39
趣味でHaskellプログラミングを楽しんでいる人達にとっては
それでいいんだろうし、それはもっともな話だと理解できる。

ただ、
717デフォルトの名無しさん:2011/01/30(日) 14:29:40
>>715
「「(A a b c)が結合できるもの」を抽象化」、ってのがよくわからない
結合法則の利点がわからないとかそういう事なら
計算の順序を変えられる→計算を楽に出来ること、っていう例を知ればいい
例えば置換行列積の問題とか
718デフォルトの名無しさん:2011/01/30(日) 14:31:01
ミス、置換行列積じゃなくて連鎖行列積
719デフォルトの名無しさん:2011/01/30(日) 14:41:22
>715
その辺の抽象化したらこんなナイスなことがあるよというのがわからんのよね・・・
使う分にはどこぞの説明であった副作用をすべて背後に押し付けて云々で良い気がするけれど。
720デフォルトの名無しさん:2011/01/30(日) 14:51:10
>>717
(A a b c) や 結合 に含まれた本質のみを抽出することを俺は抽象化と言っていて、
その抽出したものを表現するのに今のところおそらく圏論が役に立つであろうということ

(A a b c) って圏論的にはどういうこと?
結合、あるいは結合できるとは圏論的にはどういうこと?

というのを圏論の言葉で説明できると、圏論で培ってきた法則やテクニックが使える
そうして得られたものはまた Haskell の言葉で表現し直すことができそうだ

一見関係ない様々なものが群論というものに抽象化したことで理解が進んだように、
こちらは論圏で抽象化することで理解が進むのではないかと思われる


きみが「例えば置換行列積の問題とか」と言ったのも、
「(A a b c)が結合できるもの」を抽象化したものを行列の言葉で表現してる
自然に頭の中で普通に抽象化してるんだよ(特に意識してはいないと思うけど)
721デフォルトの名無しさん:2011/01/30(日) 14:52:50
それ具体化じゃね
722デフォルトの名無しさん:2011/01/30(日) 14:54:29
「それ」ってどれ?
723デフォルトの名無しさん:2011/01/30(日) 14:56:51
「これが圏論使ってこんな風に表現できるんなら、圏論のこの概念ってこういうのに応用できるんじゃね?」
ということかい?
724デフォルトの名無しさん:2011/01/30(日) 15:01:13
>>723
そういうことを期待している

ただ、まだ圏論自体を勉強してる最中だから、
本当に役に立つのかは俺自身は分らない
(役に立つことをまだ経験していない)
725デフォルトの名無しさん:2011/01/30(日) 15:04:29
最近はデータベースとかで使えるって話題もあるな。
「NoSQL=CoSQL」とか。
726デフォルトの名無しさん:2011/01/30(日) 15:11:10
幾何学から圏論に入った口だが、数学でならった圏論とはかなり隔たりがあると思うのは気のせいだろうか…
727デフォルトの名無しさん:2011/01/30(日) 15:19:10
>>711
(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を大規模に使うなんて、想像したくない苦行だと思う。
728717:2011/01/30(日) 15:24:26
>>720
自信ないが結合法則は圏論でも集合論でも意味は同じだと思う

圏論の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版は知らない
729デフォルトの名無しさん:2011/01/30(日) 17:50:00
Arrowが役立つ具体例が欲しいな
730デフォルトの名無しさん:2011/01/30(日) 20:21:04
>>729
Yampa
Grapefruit
などの FRP の実装とか

あとは ACM の Digital Library を漁ると色々出てくる
たとえば、Secure Information Flow にアローを利用する例とか
731デフォルトの名無しさん:2011/01/30(日) 22:24:12
添え字付のmapってないんでしょうか(ocamのList.mapi)
こんな感じでHoogleに入れてみたんですが見つかりません
(Integer -> a -> b) -> [a] -> [b]
(a -> Integer -> b) -> [a] -> [b]
732デフォルトの名無しさん:2011/01/30(日) 22:50:42
そういう場合は zipWith を使う

f :: Int -> a -> b
g :: a -> Int -> b

zipWith f [0..] a
zipWith g a [0..]
733デフォルトの名無しさん:2011/01/30(日) 23:35:52
なるほど、こういう時に無限リストが使えるんですね。ありがとうございました
734デフォルトの名無しさん:2011/01/31(月) 01:47:20
>>726
圏を形式体系の表現として使いたい(個々の射の形が重要)のと
関手を定義する際の枠組みとして使いたい(幾何的対象を如何に代数化するかが重要)のと
焦点が違うんじゃないかな.
735デフォルトの名無しさん:2011/01/31(月) 02:51:23
つーか、モナド関係なくね?
モナド則を自動チェックしてくれるわけじゃないし
モナド則破ってても見た目は普通に動いちゃうし
736デフォルトの名無しさん:2011/01/31(月) 03:27:12
おいハスケルプラットフォーム次期リリース
1月ってなってるのにもう1月終わるぞ
737デフォルトの名無しさん:2011/01/31(月) 23:43:52
(a, a)の両要素にa -> m bを適用する場合に、お決まりの方法ってありますか?
738737:2011/01/31(月) 23:45:08
得たいのはm (b, b)です
739デフォルトの名無しさん: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')
740737:2011/02/01(火) 00:19:53
>>739
ありがとうございます
どこかで見た気がするんですが、勘違いだったようです。
741デフォルトの名無しさん:2011/02/01(火) 00:24:30
>>737
定番の方法というのは分からないけど、三つ思いついた。

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を使えば良いのではないかと思う。
742デフォルトの名無しさん:2011/02/01(火) 00:30:31
もしa,bがどちらも多相型変数なのであれば
a -> 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]が使えそうな
743デフォルトの名無しさん:2011/02/01(火) 00:52:23
>>742
forever :: m a -> m b は、IOモナドなどを永遠に繰り返す関数。
引数の型 a は使用しないので何でも良い。
原理的に戻ってこないので、返り値の型 b は何でも良い。
というわけで、そういう方になっている。

unsafeCoerce は黒魔術にして変態技術。気にするな。
744デフォルトの名無しさん:2011/02/01(火) 07:26:51
>>742
forever は >>743 が言うように無限ループを引き起こす関数で、
FRP の活用でお世話になった

スレッドを分けて、他方を無限ループにして外部入力をポールする


unsafeCoerce はお世話になったことないな
745デフォルトの名無しさん:2011/02/02(水) 13:01:56
ghcのパッケージ依存性って厳密すぎやしない?
同じバージョンのパッケージをリビルドするだけでそれに依存するパッケージもリビルドしなきゃならない。
pkg.cabalでバージョン依存を-anyにしてもビルドするとその時のpkg-idに依存するようになっちゃう。
746デフォルトの名無しさん:2011/02/02(水) 18:52:07
ライブラリのAPIが変わってなくてもGHCから見るとインタフェースが変わり得るからだな
パッケージを跨いで積極的な最適化をすることのトレードオフで、
インタフェースファイルの内容が実装に依存することになってしまう
747デフォルトの名無しさん:2011/02/02(水) 19:05:54
しょうもない質問ですが
短いmainのいい記述法ってありますか
ghci、コンパイルエラーの時はimportしてる型の:tや:iが効かないため
とりあえずコンパイルだけしたいことが良くあるので

今のところ知ってる中では
main = return ()
これが一番短いです
748デフォルトの名無しさん:2011/02/02(水) 19:43:46
main 自体書かずに(消すかコメントアウトして)、
インポートだけ書いて ghci でリロードすればいいだけとちゃうか

そういう意味ではない?
749デフォルトの名無しさん:2011/02/02(水) 19:45:47
main=main
750デフォルトの名無しさん:2011/02/02(水) 20:01:40
>>747
( ゜Д゜)なん・・だと・・?mainは要らなかったんですね

>>748
( ゜Д゜)なん・・だと・・?型注釈付けても動きよるです
751デフォルトの名無しさん:2011/02/02(水) 20:03:26
( ゜Д゜)レス番が・・
752デフォルトの名無しさん:2011/02/02(水) 20:10:58
>>750
> 型注釈付けても動きよるです

そりゃそうだろ
動かなきゃ再帰なんてできない
753デフォルトの名無しさん:2011/02/02(水) 21:13:47
main = undefined
754デフォルトの名無しさん:2011/02/03(木) 09:37:55
Current stable release: 2010.2.0.0 (July 2010)
Next release: January 2011
Problems?
755デフォルトの名無しさん:2011/02/05(土) 13:57:36
バレバレな気がするけど、Control.Monad.joinのjoinは最小上界(上限)
という意味で正しい?
http://en.wikipedia.org/wiki/Join_and_meet
756デフォルトの名無しさん:2011/02/06(日) 00:02:33
>>755
よく分からないけど、どうしてそう思うのか教えてほしい。
757デフォルトの名無しさん:2011/02/06(日) 01:15:47
Haskell の型クラスとそのインスタンスとなるデータ型の関係を図示しようとする時、
UML のクラス図のクラスとインスタンスの関係と同じように
両者を結んだ線のクラス側に三角形を描くようにするのでしょうか。

それとも、Haskell では一般的な図示の方法は提案されていないのでしょうか。
758デフォルトの名無しさん:2011/02/06(日) 01:38:25
>>756
あんまりまとまっていないからうまく説明できないけど、
前にスレに貼られていた論文
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という用語を持ち出すことになる、
それは、少し考えにくいんじゃないか、と思ったから。
759デフォルトの名無しさん:2011/02/06(日) 02:13:45
そのあたりの分野って、日常生活でも使うようなありふれている語をテクニカルタームとして使うからなぁ。
ウェブ検索するのにたいへん都合が悪い。
もうちょっと変な語を定義して欲しいもんだ。
760デフォルトの名無しさん:2011/02/06(日) 11:03:17
>758
> 理論計算機科学の人たちは、
> 表示的意味論、束論、圏論、モナドを知りながら、

関数を書く人全てが,意味論,圏論その他を統一された形で理解しているとは限らないし.

定義を見ると,Control.Monad.join は(圏論の)モナドの構造射のようだから,もっと適した
名前があると思う.「リスト関数の一般化」に分類されているから歴史的な理由で
join という名前がついているのだろう.

> HaskellのControl.Monad.join(モノイドでは積にあたる)
モノイドの積は二項演算だから例示としてあまり良くないのでは?
761デフォルトの名無しさん:2011/02/06(日) 11:44:49
>>758
数学詳しくないのでよく分からないけど、例えば次のような定義をした場合、

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
-- つづく
762デフォルトの名無しさん:2011/02/06(日) 11:48:36
この join は Cotrol.Moad のjoin とほぼ同等で、かつ、集合の包含関係を順序関係とした場合の結び(join)になっていると思う。
だから、この場合は概念的に関係があるけど、モナド一般に拡張できるかどうかはよく分からない。
763デフォルトの名無しさん:2011/02/06(日) 12:16:15
>>760
プログラムを書いた人がどうだったのかはわからないけれど、
Haskellにおいて華形だとみなされて当然な概念であるわけだから、
関与しているそれぞれの分野から注目されるという見込みは立つ。
開発指導層としては、華形のところにうっかり変な名前をつけちゃって
台無しになるなんて事態は避けるのが普通。必ずチェックを入れたはずだ。
でも、μにjoinという名前をつけたということは、何かしら他人を説得できる
理由というか名目があるんだろう。

二項演算ではないけど、型の二重入れ子を一重にしてくれて、図式を比較したら
対応しているところにあたるわけだから、対応しているといっても良くない?
積じゃなくて余積だといわれるのなら分かるけど。
764デフォルトの名無しさん:2011/02/06(日) 12:21:52
>>762
サンクス。読んでみる。
そういわれてみると、モナドで完備半束を表現できないとおかしい。
765デフォルトの名無しさん:2011/02/06(日) 12:39:42
でも、μにjoinという
だと意味がわかりにくくなるな
それでも、μにjoinという
で。
766デフォルトの名無しさん:2011/02/06(日) 12:58:26
>763
トップダウンでライブラリや関数を作る場合はあなたの仰るとおりだと思う.
一方でローカルな関数/一時的な関数を一般化してライブラリに収めた,という場合
諸般の事情でオリジナルの名前が残ったとしてもおかしくない.いつか適切な名前に
改められるべきだとは思うけども.
経緯を知らない状況で「合理的な理由がある」と決め付けることは私にはできない.

>762
Control.Monad.join は要素の重複をそのまま残すので,いわゆる集合の join にはならないと思う.
767デフォルトの名無しさん:2011/02/06(日) 13:01:43
>>761
動かしてみたけど、確かに結び(join)になっているようだ。
意味論とトポロジーは関係あるそうだし、結び目の理論もモナドで実験できる
のかもしれん。全然知らないけど。
768デフォルトの名無しさん:2011/02/06(日) 13:04:30
>>766
前後した。重複を許すとはどういう風なもの。
769デフォルトの名無しさん:2011/02/06(日) 13:34:26
Listのjoinはただのfattenだから
join [[1,1],[3,4]] は[1,1,3,4]
1は重複してるけど、これが問題になるってこと?
770デフォルトの名無しさん:2011/02/06(日) 13:39:40
>768
join [[1,2,3],[2,3]] = [1,2,3,2,3]

{1,2,3} \/ {2,3} = {1,2,3}

ちなみに領域理論で使われるのは general topology で,結び目とかのいわゆる
「トポロジー」とは(多くの場合)大きく異なる.

あと,念のために書いておくと結び目は knot/link だからね.
771デフォルトの名無しさん:2011/02/06(日) 13:40:02
このページは主要な型クラスについてよくまとまっていていいな
ここにいる人には必要ないかも知れないけど
ttp://snak.tdiary.net/20091020.html
772デフォルトの名無しさん:2011/02/06(日) 13:53:22
>>770
なるほど。なるほど。調べてみます。
773デフォルトの名無しさん:2011/02/06(日) 18:55:50
なるほど〜!なるほどぉ〜!
774デフォルトの名無しさん:2011/02/06(日) 20:28:05
μはleast fixpoint
νはgreatest fixpoint
っていうのは再帰理論関係の方言みたいなものだから
Monadにおいてμでjoinを表わすのはjoinの定義が
μ. T T = T
になってることから来てるように思えるんだけど
何故greatestじゃなくてleastなのかってのがよくわからん
CPO(完備半順序)で μ (T(T(X)) < T(T(X))ってなってるってことなんだけど
直感ではネストが減ってるからとかそんな感じでgreatestはありえんという気はするけど
型付きラムダ計算の世界におけるCPOとしてはもう少し厳密な定義があるはずだよね
775デフォルトの名無しさん:2011/02/06(日) 21:43:16
>>774
理論的にはそういう感じで推測しました。
もし余モナドがあればjoinじゃなくてmeet(最大下界)になって、
最大不動点を意味するのかなと。
776デフォルトの名無しさん:2011/02/06(日) 22:20:16
付け加えて、内容を理解していないので言いがたいのですが、
圏論の基礎のp150に積はmeetで余積はjoinだ、という話が書いてあります
そこが関係するような。
でもそうすると、joinじゃなくてmeetにするべきのような気がしますね。
(余積の図式なので。)
777デフォルトの名無しさん:2011/02/07(月) 15:56:05
SunOS(SPARC64)上で、darcsを使いたいのですが、どんな準備をすればよい
か教えてください。Linuxなどの場合は、
- Haskell Platformをインストールする
- それに含まれているcabalを使う
という手順のようですが、Haskell Platformのページに行くと、
Windows,Mac,Linuxのみの対応のようです。
778デフォルトの名無しさん:2011/02/07(月) 16:08:08
>>777
Solaris用の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
779デフォルトの名無しさん:2011/02/07(月) 16:34:08
>>778
ソースのダウンロード先誤記失礼しました。
ttp://hackage.haskell.org/platform/linux.html
780デフォルトの名無しさん:2011/02/07(月) 18:03:38
最近、忍者さん…
どうしてるんやろ・・・・
781デフォルトの名無しさん:2011/02/07(月) 20:19:44
リストで最初にマッチした要素に処理をしたいです
foldではマッチ後も余分な計算が発生するので
次のような関数を考えたのですが
既に用意されてる関数を組み合わせてこういうの出来ないでしょうか
(言い換えると、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..]
782デフォルトの名無しさん:2011/02/07(月) 20:33:38
import Data.List(find)
result = fmap (*2) $ find (==20) [1..]
783デフォルトの名無しさん:2011/02/07(月) 20:42:55
>>781
dofirst :: (t -> Bool) -> (t -> a) -> [t] -> [a]
dofirst p f = maybeToList . fmap f . find p

これが同じ関数になっているはず。
ただ、これが本当にやりたいことなのか疑問に感じる…
784デフォルトの名無しさん:2011/02/07(月) 20:52:44
>>780
バトルロワイヤルスレにいるPerl評論家ってのが奴じゃないのか?
785デフォルトの名無しさん:2011/02/07(月) 20:56:34
>>782-783
短い!エラー処理ではなくMaybeかー
やりたかったことは
dofirst p f = fmap f . find p
こうでした
786デフォルトの名無しさん:2011/02/07(月) 21:24:15
名前がどうのと言うのであれば、 return がうまくないけど歴史的経緯で仕方がないというのも Haskeller の共通認識だろ。
そんなにキッチリした経緯で決まっていると思わない方がいい。
理論の部分はともかく、用語は人間的な感覚の影響を受けるし。
787デフォルトの名無しさん:2011/02/07(月) 21:38:34
return はうまくないというか、最大の汚点だと思うが、
もう今更だから諦めてるよね、みんな
788デフォルトの名無しさん:2011/02/07(月) 22:35:17
returnが汚点なんて誰が主張しているのよ?
789デフォルトの名無しさん:2011/02/07(月) 22:39:41
>>780
説着曹操 曹操就到
790デフォルトの名無しさん:2011/02/07(月) 22:42:13
>>788
return という名称がダメだというのはみんなも認めるだろ
791デフォルトの名無しさん:2011/02/07(月) 22:49:51
>>790
理由としてはどういったものがあるの。
自分は結構マッチしていると思っているのでダメだというのがわからない。
792デフォルトの名無しさん:2011/02/07(月) 23:05:50
プログラマは return と聞くと脊髄反射で関数の戻り値を想像するけど、この return は関数の戻り値とはまったく無関係だから

let f = return "test1" >> putStrLn "test2" >> return "test3" >> putStrLn "test4"

fの戻り値は "test1" でも "test3" でもない
793デフォルトの名無しさん:2011/02/07(月) 23:07:25
>>791
逆に何にマッチしてるのか訊きたい
794デフォルトの名無しさん:2011/02/07(月) 23:09:30
個人的にはm a -> aのほうが、まだreturnしてるなぁと思う。コモナド
795デフォルトの名無しさん:2011/02/07(月) 23:09:59
do 記法とセットで使うときになんとなく C とかで言う return と似た雰囲気になる気がする、という程度。
796デフォルトの名無しさん:2011/02/07(月) 23:12:34
>>795
入門者にそう勘違いさせてしまうのが return の最大の問題だ
797デフォルトの名無しさん:2011/02/07(月) 23:14:41
>>793
>>=をコマンドラインのパイプのように理解しているから。
return aでaをパイプで処理できる形に変換
>>= f で処理可能にしたaに対してfを適用、で考えている。
798デフォルトの名無しさん:2011/02/07(月) 23:36:28
>>791
もしやC/C++とは無縁のお方?
799デフォルトの名無しさん:2011/02/07(月) 23:43:28
>>798
計算を返すという意味でC/C++のreturnとも合致していると思うが。
800デフォルトの名無しさん:2011/02/07(月) 23:54:15
例えば1をパイプでつないでcatすることを考えた場合
> 1 |cat
というのはできない
> echo 1 |cat
としなくてはいけない。
入出力をたとえとして出しちゃっているので多分変な誤解が出るけど、
言いたいことは、ここでいうechoにあたるのがreturnだという意図なのだと思う。
echo :: 何か値 -> 入出力
だけど
return :: 何か値 -> モナド(というかコンピュテーション)
と一般化したものだと理解している。正しいかどうかは知らない。
だけど、そんな感じの論理でreturnと決まったんじゃないのかなぁと。
801デフォルトの名無しさん:2011/02/07(月) 23:59:06
return が圏論的用語とどうこう、手続き型言語のreturnと云々はともかく、Hakellのクラス体系のMonadがApplicativeのサブクラスでないのは審美的に気持ち悪いで、なんとかして欲しい。
WrapMonadとか意味わからなすぎる。

あと、Functorクラスの(.)とidは別のクラスにしておけとか、ArrowクラスのarrがArrowChoiceと対称性を損なっていてキモイとか。
802デフォルトの名無しさん:2011/02/08(火) 00:07:55
>>785
foldlだと駄目だと思うけど、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..] => _|_
803デフォルトの名無しさん:2011/02/08(火) 00:18:33
「return 0」 は 0 を返してるんじゃなくて、 整数型の0をモナドに入れて別のモノに変換してるんだよね
804デフォルトの名無しさん:2011/02/08(火) 00:26:55
>>801
理論的に美しいとか別にどうでもいいよ。
実用的に便利な組み合わせがあるのならそっちを優先するべきだし。
そもそも満足に綺麗に出来る保証なんてない。
自分は一般的に使えそうなところを探しているだけだよ。
805デフォルトの名無しさん:2011/02/08(火) 00:40:49
目指すなら無駄のない機能美だよ。
机上と実践じゃ必ずギャップ出るんだから。最初から現実的な落とし所で
考えておいたほうがリスクが少ないよ。
806デフォルトの名無しさん:2011/02/08(火) 00:57:30
実用的じゃないものよくやられるねクズどもは
かわいそうだね

言語オタとか死ねばいいよこういうやつら
何もつくれねえじゃん
なに作ってるのかな?

エジソン気取ってんの?笑
807デフォルトの名無しさん:2011/02/08(火) 01:00:30
>>804,805
そりゃ、理論的な美しさと実用性を比べれば実用性のほうが勝るかもしれないけど、MonadがApplicativeのサブクラスでないことは、実用性も損なっていると思うな。
ライブラリ製作者が注意すればよいこと、Contorl.なんちゃらカコイーな変態(オレとか)がいちいちinstance宣言かけばよいことではあるが、それでも僅かにであっても実用性を損なっている。

>>806
変態で悪いか? あぁ、悪いのか? オレが変態でお前に迷惑かけたか?
ああ、オレは変態だよ。それが何か問題か?
808デフォルトの名無しさん:2011/02/08(火) 01:01:37
平日の深夜に 2ch で煽ってる人はどういう人だろう
809デフォルトの名無しさん:2011/02/08(火) 11:21:53
>>806
芋(IMO):
- OCamlはネイティブバイナリ作るときにコンパイル時に使用するライブラリライセンスはLGPL (商用アプリ作るときに色々と面倒)
- 今後ゲーム開発は関数型言語が主流になるかもしれない話や研究活動は数年前からある。Haskellはその候補のひとつと考えている。
- 探すと意外と使われているし、開発も盛んである。あと俺のところで立ち上げる予定のサービスにC/C++, Perl, Ruby, PythonではなくHaskell使う予定だから(変態Haskell初心者で何が悪いか!)
- HaskellでOSを書いている人はたしか実在する。Houseだっけな。つまりGHCを使用してシステム記述にも使おうと思えば使える。

要するに頭の悪い否定癖を捨てて物事を両面から見ろってことだ。
810デフォルトの名無しさん:2011/02/08(火) 12:03:45
凄くっても取っ付き辛いと普及はしないんじゃないかな
811デフォルトの名無しさん:2011/02/08(火) 12:45:00
return が変と言ってる人達(俺も含めて)は、
return が行う事、return が担っている役割が変なのではなく、
そういうものに return という名前が付いていることに違和感を感じている(と思う)
812デフォルトの名無しさん:2011/02/08(火) 14:19:46
自己レス>>801

(.)とidは、Categoryクラスでした///
813デフォルトの名無しさん:2011/02/08(火) 15:16:50
>>801
(.)とidを別のクラスにするのはどうして?
射の結合(.)とその単位元(id)は切っても切れない関係のような気がするけど。
814デフォルトの名無しさん:2011/02/08(火) 17:10:13
>>811
とっつきにくさは情報の整備によりある程度は解決するので
時間とコミュニティの方針の問題かな。

あと必要なら何故か存在しないGHCのユーザーズガイドの完訳を半年程度で
やるけど成果と最新安定版とのバージョン同期は期待しないでね(他も一人でやると半年では終わらない)。
815デフォルトの名無しさん:2011/02/08(火) 18:20:10
>>802
遅延評価!foldでは無理だと思っていました。なるほど、不思議

再度挑戦して
dofirst2 pred f x = find pred x >>= return .f
を経て
dofirst3 pred f = liftM f . find pred
→liftMとfmapって似てるなと思っているところです
816デフォルトの名無しさん:2011/02/08(火) 19:54:41
>>813
> 射の結合(.)とその単位元(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でもある型では必須の要件らしい。
817デフォルトの名無しさん:2011/02/08(火) 21:34:07
>>807
Applicativeはほとんど知らなかったのだけれどこれ?
ttp://www.soi.city.ac.uk/~ross/papers/Applicative.pdf
解説のほう読んだ限りだとなんというか、関手じゃないなにかマッピングするもので
写した射を関手のように取り扱いできるようにする、というのが基本アイディア
のようだね。
言いにくいし、よく知らないけど、これ実用面からの要請のみだと思うぞ。
(.)とidの話は正直よくわからん、どういうこと?
Arrowは全く知らないのでわからない。

liftMは循環的性質を持つ関手の射関数と考えればいいと思う。
818デフォルトの名無しさん:2011/02/08(火) 21:53:51
関手のように取り扱いできる
じゃおかしい
関手を適用したように取り扱いできる
で。
819デフォルトの名無しさん:2011/02/08(火) 22:07:13
>>816
サイト情報ありがとうございます。
>>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)もなんかのコンビネータと対応してるのかも
820デフォルトの名無しさん:2011/02/08(火) 22:26:34
>>817
ごめん。オレには>>816以上にうまく説明できないし、オレが何か勘違いしている可能性もある。
821デフォルトの名無しさん:2011/02/08(火) 22:56:42
>>819
一応これ読めば対応はわかるとおもう。
ttp://www.ipsj.or.jp/07editj/promenade/4703.pdf
モナドの構成要素に関手が入っているので、理論としてはモナドと関手は切り離せない。

fmapとliftMはつかう文脈によりけりでいいんじゃないか。
他の領域に写すだったらfmapで上の階層(コンピュテーションの世界)に
上がるだったらliftMとか。

>>820
普通のidと関手F上のid_Fとで区別する必要があるとかならあるのかもしれないけど
よくわかんない。
822デフォルトの名無しさん:2011/02/08(火) 22:57:44
関数プログラミングの楽しみという本にArrowのことがちょこっと書いてあったけど、圏論とか関手そのものの説明がはしょってあったので、圏論とHaskellの関係がよくわからなかったです
その圏論からモナドまで説明してある本ってないですかね?
本屋にいったけど、圏論の本なかったです
823デフォルトの名無しさん:2011/02/08(火) 23:05:04
>>822
さっきも書いたけど対応としてはこれ
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/
さがすと結構あるし、自分も探し中。
824デフォルトの名無しさん:2011/02/08(火) 23:12:37
ただ上のは隙がないように書かれてて正直わからないので
個人的にはつくりながらわかるこれがオススメ。
ttp://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.2885
Schemeだけど。
825デフォルトの名無しさん:2011/02/09(水) 00:24:45
言えないっ
いまさら英語が読めないなんて言えないっ
826デフォルトの名無しさん:2011/02/09(水) 02:01:42
>>814
えっと、ごめん。http://www.kotha.net/ghcguide_ja/latest/ とは別のもの?
827デフォルトの名無しさん:2011/02/09(水) 12:07:39
>>826
これは失礼。あったのですか。
他に訳されていないもの探してみます。
828デフォルトの名無しさん:2011/02/10(木) 00:44:47
お前らの議論についていくには
バチェラーだけじゃ無理
829デフォルトの名無しさん:2011/02/10(木) 00:50:42
お前等の中で、圏論の知識が Haskell でのアプリ製作、
ライブラリ製作に役立ったよ、って経験者はいる?
830デフォルトの名無しさん:2011/02/10(木) 01:10:36
ポルトガル語専攻だけど、圏論の基礎を買ってきたよ
さっぱり分からん
831デフォルトの名無しさん:2011/02/10(木) 07:52:22
for the working mathematicianだからな
邦題を決めた奴は地獄の業火の中に投げこまれるべきである
832デフォルトの名無しさん:2011/02/10(木) 17:41:19
>>801
Arrow が Categoryのサブクラスなので (.)とidを Categoryクラスで定義するのはしょうがないと思うが。
> ArrowクラスのarrがArrowChoiceと対称性を損なっていて
これはどういう意味?
833デフォルトの名無しさん:2011/02/10(木) 23:03:22
>>832
自分の言葉で言わないとわからなくなるだけだよ。
Arrowは全く知らない。機能を難しくしても、個別の機能にまつわる話が
分散化していくだけで、あんまり意味というか仕事にならないと思う。
834801:2011/02/10(木) 23:51:50
>>832
Arrow から 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 が集合の直和に相当することを考えても、この対称性(あるいは双対性?)は明白だと思う。
835デフォルトの名無しさん:2011/02/11(金) 01:20:48
対称性があると思うんだけどどこが「対称性を損なっていて」るの?
836デフォルトの名無しさん:2011/02/11(金) 01:31:29
ああ arr があるかないかの一点だけが対称性を損なっているという意味か。
837デフォルトの名無しさん:2011/02/11(金) 14:53:33
Steve Awodey の「Category Theory SECOND EDITION」で圏論を学んでみようとしたが、
途中まで読んでだいぶ挫けそう、というか飽きかけてる

圏論を知っていたから Haskell でこういうプログラムができるようになった、
Haskell のこういう事が理解できるようになったとかいう自慢話は何かない?

圏論を学ぶ道の先に Haskell の輝きが見えるとモチベーションが維持できるのだが
838デフォルトの名無しさん:2011/02/11(金) 17:53:08
807
>>変態で悪いか? あぁ、悪いのか? オレが変態でお前に迷惑かけたか?
>>ああ、オレは変態だよ。それが何か問題か?

>>807
変態気取り うわ〜お前みたいなやつ人のまね

変態的コード とかいうやつの真似
yusukebeのまね

お前は真似野郎猿真似帰れよ猿
チンパンだね キモ
839デフォルトの名無しさん:2011/02/11(金) 18:16:56
>>837
10章まで行って、やっとモナド則が必要な理由が分かる程度
840デフォルトの名無しさん:2011/02/11(金) 22:01:08
役に立った話をしつこく聞きたがってる人

うん、君の役には立たないし義務教育ってわけでもないから
話がわからないなら教室から出ていっていいのに
座り込んで泣くわ喚くわ小便を漏らすわ
もうね
841デフォルトの名無しさん:2011/02/11(金) 22:21:35
しつこくって、>>837 で初め訪ねたんだが

圏論の Haskell への応用って話は私だけでなく、
他の人も知りたがっている事だと思ってたが、違うのか?
きみは知りたくないのか?
842デフォルトの名無しさん:2011/02/11(金) 23:37:28
オレも、Haskell の勉強の一環として『圏論の基礎』を買ったけど、すぐに挫折したくち。

ただ、それでも、以前も書いたことだけど、オレは 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"
843デフォルトの名無しさん:2011/02/12(土) 00:10:58
>>840
分からないなら分からないと素直に言った方がいいと思う
844デフォルトの名無しさん:2011/02/12(土) 00:20:43
>>842
モノイドは圏なのに、圏に変換する理由が分からないです

あと、「圏論の基礎」は日本語がおかしい
845デフォルトの名無しさん:2011/02/12(土) 00:29:40
圏論を勉強するのに圏論の基礎に手を出すのは絶対にやめたほうがいいと思うわ。
ワケわかんねぇもんあれ。
英語でもAwodeyの本とかの方がよっぽど分かりやすい。

日本語なら分量が少ないけど
http://www.amazon.co.jp/dp/4320026578
の圏論の章が比較的わかりやすいと思う。
絶版なんで図書館かどっかで借りるしかないけど。
846デフォルトの名無しさん:2011/02/12(土) 08:53:16
こんにちは。
学校でHaskellを選択して今>>4の・Haskell: The Craft of Functional Programming を読んでいます。
それで少し分からないのが

square ::Int ->Int
square n= n*n
です。

すみませんが中々分からないので教えていただけませんか?おねがいします。
847デフォルトの名無しさん:2011/02/12(土) 09:45:42
それの何がわからない?
848デフォルトの名無しさん:2011/02/12(土) 11:41:54
うーん、皆が理論的な話をしている中でアレだけど、やっぱりcabalがパッケージの依存関係を壊すことが納得できない。
ソースコードとコンパイルしたプログラムが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を作らない
どっちかで解決できるはずなんだけどなあ。
849デフォルトの名無しさん:2011/02/12(土) 12:40:43
QuickCheckがあるから強気に出てると推測
850デフォルトの名無しさん:2011/02/12(土) 14:56:47
err 関数や undefined 関数は副作用を持つのか、持たないのか・・・
ちょっと気になった

まぁ、ホントどっちでもいいことだが
851デフォルトの名無しさん:2011/02/12(土) 15:22:20
>>846
あなたが何が分からないのか、こっちには分からない・・・

一行目の「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は一つしかないので両方の要件を満たすことはできない、という問題だと理解してよい?
852デフォルトの名無しさん:2011/02/12(土) 15:54:25
>>851
うん。>>848の記事にもあるけど、.cabalファイルのバージョン指定がパッケージによって厳しすぎる/緩すぎるのも一因。
で、殆どのパッケージ、応用ソフトがそんな依存関係を持ってる。
ttp://www.mail-archive.com/[email protected]/msg72276.html
このCabal dependency hellのスレッドも似たような問題の話をしてる。
hackageに上げたパッケージは、バージョンを変えずに.cabalファイルの記述を変えることができないのが問題だとか、
いやそういう修正をするならfoo-0.5をfoo-0.5.1と微修正してくれるよう開発者にお願いすればいいとか、色々言われてる。

個人的にはパッケージャーが全バージョンの動作検証をするのは大変だから、利用者の報告、検証をもっと簡単にできた方がいいと思う。
他には、自分の使ってるディストリだと内部のソースの変更ではない、パッケージ情報の変更だけとかの場合、
バージョン番号の他にあるリリース番号を上げて対応するとかしてる。依存関係の記述にリリース番号を含むことはできなくしてる。
853Perl評論家:2011/02/12(土) 15:56:59
ここのスレは害

見るだけで頭が痛くなる
854デフォルトの名無しさん:2011/02/12(土) 16:14:44
おいおい、忍者から評論家へジョブチェンジかよ
技が引き継がれてると鬱陶しいな
855デフォルトの名無しさん:2011/02/12(土) 16:17:27
>>850
error :: [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# の実装は、たぶん普通のラムダ計算の枠組みに収まらないものになっているだろうけど、それを「副作用」と呼ぶのが適切かはよく分からない。
856デフォルトの名無しさん:2011/02/12(土) 19:02:54
>>851
>(Intが何bitかは、厳密には環境依存だったはずだけど、たいていは32bit)
64bit版のLinuxではIntは64bitみたい。
Cのintは32bitのままだから、ちょっと意外だ。
64bit版Windowsではどうなってるのかな。
857デフォルトの名無しさん:2011/02/12(土) 22:57:48
次のような関数を作りました。

fix :: (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 型のソースを見てみましたが、(==) 関数の定義は重そうですし、実際重いです。
指している対象同士で比較できれば処理速度が速くなるのですが。
858デフォルトの名無しさん:2011/02/13(日) 00:05:44
やっぱここだと話がまとまらん。
どこか別に話ができるところとかないもんですか。
859デフォルトの名無しさん:2011/02/13(日) 00:09:30
>>857
モナディックになってしまうが、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
}

つづく
860デフォルトの名無しさん:2011/02/13(日) 00:13:11

http://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 を使っているかぎり、(==)は要素の比較のみしてくれるはず。

モナディックにするのがいやなら、配列を生成/変更するときにハッシュ値でも計算してそれを比較するようにするとか。
861デフォルトの名無しさん:2011/02/13(日) 12:56:25
>>859
>>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 なら終了とか。

両方の方法で試してみます。
アドバイスありがとうございました。
862デフォルトの名無しさん:2011/02/13(日) 18:43:37
>>861
> 要素の比較ではなくて、参照で比較するから速いんですよね。

あれ? なんで、「要素の比較」なんて書いたんだろう。
おっしゃるとおり、「参照の比較」の誤りです。ごめん。
863デフォルトの名無しさん:2011/02/15(火) 00:27:53
いったいいつになったら日本語ネイティブ対応するんだよ!
864デフォルトの名無しさん:2011/02/15(火) 06:39:56
IOモコナ
865デフォルトの名無しさん:2011/02/15(火) 07:15:50
日本語に対応させる必然性が感じられないよな
866デフォルトの名無しさん:2011/02/15(火) 10:09:40
>>865
ふたばみたいなBBSつくりたいんだけど、
今は、むりやり日本語を数字にコーディングしてデータベースに保存してる

AAがあるので、Shift_JISを扱いたいです
867デフォルトの名無しさん:2011/02/15(火) 12:35:00
>>866
ライブラリじゃいかんのか
868デフォルトの名無しさん:2011/02/15(火) 13:28:01
YassieとAphaiaの対立の本当の原因って何なの?
例の氏名公開事件は完全にAphaiaに問題があると思うけど、Yassieがあそこまで激しく嫌悪しているのは、それじゃないでしょ?
869868:2011/02/15(火) 13:33:24
ごめん。誤爆。
ほんとうにごめんなさい。
870デフォルトの名無しさん:2011/02/15(火) 13:53:49
ハスケルが今一つ流行らないのは
Haskellくだ質スレが無いから
871デフォルトの名無しさん:2011/02/15(火) 23:05:51

State型を返すreturnへの型注釈はどうやって付ければいいですか
statereturn :: a -> State ???
statereturn = return

最終的にやりたいことは
ttp://www.sampou.org/cgi-bin/haskell.cgi?Memoise
ここにあるmemoise/ins/findにState型を使って型注釈をつけることです
872Perl忍者 ◆M5ZWRnXOj6 :2011/02/16(水) 00:55:33
かわいそうだねぇ・・・なんどみても
873Perl忍者 ◆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;\  ,,.ゝ;;;;;;;;;;;;;;;;;;;;;;;;;;;
874デフォルトの名無しさん:2011/02/16(水) 01:02:33
>>871
a -> State s a じゃない?
875デフォルトの名無しさん:2011/02/16(水) 03:40:28
872 :Perl忍者 ◆M5ZWRnXOj6 :2011/02/16(水) 00:55:33
かわいそうだねぇ・・・なんどみても


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;\  ,,.ゝ;;;;;;;;;;;;;;;;;;;;;;;;;;;
876デフォルトの名無しさん:2011/02/16(水) 09:25:10
自己記述的とは実に素晴らしい
877デフォルトの名無しさん:2011/02/16(水) 14:47:01
カーゴ・カルトって何?
878デフォルトの名無しさん:2011/02/16(水) 15:33:49
ググれ
879デフォルトの名無しさん:2011/02/16(水) 16:43:50
Stateモナドの勉強中です。

import 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が加算されました")をするにはどうすればいいんですか?
できれば実際にコードを書いてください。
よろしくお願いします。
880879:2011/02/16(水) 17:03:37
もしかしてこんな感じですか?
addHP :: 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
881デフォルトの名無しさん:2011/02/16(水) 18:35:34
>>874 解決しました。ありがとう

>>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
882デフォルトの名無しさん:2011/02/16(水) 19:57:54
>>880
たぶん、理解しているんだろうけど、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)
883デフォルトの名無しさん:2011/02/16(水) 21:52:45
>>882
演算子の定義の仕方と、dummyが要らない書き方がとても参考になりました
whereのほうが宣言的に見えますね

mtlのバージョンは1.1.0.2(HaskellPlatformの付属品)でした
道理でStateコンストラクタを使ってるコードをあまりみないわけか
Readerのコンストラクタが使えるのに気づいて
類推から使ったら動いたもので
884Perl忍者 ◆M5ZWRnXOj6 :2011/02/17(木) 09:20:51
ひゅひゅっだよ

みんな、あさだよ
885デフォルトの名無しさん:2011/02/17(木) 14:26:02
ひゅ〜 ひゅ〜
いぇ〜い
886デフォルトの名無しさん:2011/02/17(木) 14:29:53
リストのn番目の要素を更新する(n番目の要素を更新した新しいリストを返す)方法を教えてください。
それとも頻繁な更新にはリストは不向きですか?
887デフォルトの名無しさん:2011/02/17(木) 16:15:56
リストをxs、n番目に置き換える新しい要素をxとすると

take n xs ++ [x] ++ drop (n+1) xs
888デフォルトの名無しさん:2011/02/17(木) 17:08:24
f xs n x = [if i == n then x else e | e <- xs | i <- [0..] ]
889デフォルトの名無しさん:2011/02/17(木) 17:40:14
>>886
頻繁に更新するなら Data.Map のほうが効率的。
890デフォルトの名無しさん:2011/02/17(木) 17:46:44
>>885
浜崎あゆみとかノネナールキツいよおじちゃん
891デフォルトの名無しさん:2011/02/17(木) 17:50:12
桃の天然水の人だと思った漏れはいったいどうしたらいいですか
892デフォルトの名無しさん:2011/02/17(木) 17:52:23
>>886
ハスケル詳しくない俺が答えるけど
ハスケルは参照透過性の為に基本、更新=新しく作り直し
だから遅いよ。膨大なデータを一カ所書き換えるが為に
別のメモリ空間に変更無しの所まで一からコピーし始める様を想像してみなよ
頻繁な更新には向かないね。

勿論策はある。それは他の人たちが答えてくれるよ
893デフォルトの名無しさん:2011/02/17(木) 17:54:12
>>891
あ、小室てつやに振られてメンへラになった女の方だっけ?
いずれにせよ加齢臭するわ
894デフォルトの名無しさん:2011/02/17(木) 18:08:18
>>892
> 膨大なデータを一カ所書き換えるが為に
> 別のメモリ空間に変更無しの所まで一からコピーし始める様を想像してみなよ

普通の実装だと、変更無しの所まで一からコピーされはしないよ

変更ヶ所の部分だけ、ポインタを指し替えるだけ
895デフォルトの名無しさん:2011/02/17(木) 18:37:00
>>894
あり^^

走査はあるの?

ここは前と同じだからパス
ここもパス

あ、ここは変更点ね。新規生成してポインタ差し替えます
ここはパス
ここもパス

はい終わり

膨大なリストになるとこれでも馬鹿にならないコストでは?
896デフォルトの名無しさん:2011/02/17(木) 18:54:12
>>892
こんな感じで、詳しく無いとか、わかる範囲とか
そういう答え方しか出てこないのが怖い
haskell刷れ
897ぱるぱる:2011/02/17(木) 19:05:32
ひゅひゅだよ

みんな、ばん御飯の時間だよ
898デフォルトの名無しさん:2011/02/17(木) 19:54:22
>>895
君は >>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 の比喩は、そのようなリスト操作が遅いことを理解する比喩としては全く的外れだ
899デフォルトの名無しさん:2011/02/17(木) 20:39:33
メンヘラの言う訳のわからない世界はあった。
現実世界ともう一つ、訳のわからん世界の二層構造だったということだ。
900デフォルトの名無しさん:2011/02/17(木) 20:40:35
>>898
あり^^
901デフォルトの名無しさん:2011/02/17(木) 20:50:54
>>898
そんな実装しだら前の[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個ブロックだ。
リストの一部更新をする場合、入れ物を元のリストと同じ数だけ作って、中身を指し示す先をちょっと弄るだげだ。
902デフォルトの名無しさん:2011/02/17(木) 21:04:38
>>901
フォローに感謝する
903デフォルトの名無しさん:2011/02/17(木) 22:06:23
おまえら、どんだけ混乱してんだwwwww

あるリストから一部変更したリストを作成する場合、一般的には
・ コンスセル(コンテナ、データコンストラクタ(:))の中身を書き換えるだけで足りるとは限らず、たいていは新しいコンスセルが必要。よって、>>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 : [] で、この場合、新しいコンスセルは、二つ必要。
必要なコンスセルはゼロでも、四つでも、五つでもない。

二つ。
904デフォルトの名無しさん:2011/02/17(木) 22:50:44
ドリフ(笑)
905デフォルトの名無しさん:2011/02/17(木) 23:51:41
906デフォルトの名無しさん:2011/02/18(金) 02:04:06
何故かメモリを数百MB食うようなプログラムってどうすりゃいいんですか?
プロファイルとって何処がヒープ使ってるのかがわかっても、いったい何故なのかがわからないから
直しようがないという……
いやこれだけじゃ回答しようがないとは思うんですが、実際原因に検討すらつかないから相談も難しい。
907デフォルトの名無しさん:2011/02/18(金) 07:10:00
>>906
可能性の話しかできないけど。
とくに思い当たる節がないのなら、リストのクロージャが大変なことになっているのかもしれない。
リストの操作を手書きでできるだけ一個のfoldrにまとめたらうまくいくか、それに取り組むことで原因が分かるかもしれない。
908デフォルトの名無しさん:2011/02/18(金) 07:17:12
>>906
下記のサイトの最新記事(第45回 GHCの性能測定機能でボトルネックを探す)を参考に、
もう少し詳しい検査をしてみるとか

http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248215/?ST=ittrend
909906:2011/02/18(金) 13:13:18
SCCで分析したけどやっぱり解決法がわかりません。
誰か親切な人、軽いヒントだけでいいのでください。
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って初めて知りました。
便利なので今試してます。
ありがとうございます。
910Perl忍者 ◆M5ZWRnXOj6 :2011/02/18(金) 14:03:19
ひゅひゅだよ

みんな、おやつは何んですか?
911デフォルトの名無しさん:2011/02/18(金) 14:53:19
きのこの山
912デフォルトの名無しさん:2011/02/18(金) 14:54:37
圏論が理解出来てないやつはhaskellを使う資格は無いな。
俺はそう思う。
913Perl忍者 ◆M5ZWRnXOj6 :2011/02/18(金) 15:09:39
>>ライトニングトークスでUjihisa君の話「JavaScriptとHaskell」が興味深かった。
Haskell読書会に出たものの、どうしてもHaskellのソースは読めなかったけれど、
JavaScriptで置き換えてくれてようやく、Haskellが分かった気がした。

なんでjavascriptやてるやつがわざわざ,Haskellやって
まわりの奴がjavascriptで置き換えてあげないといけないの?

ばかなんじゃないの?
こいうやつは、すぐハテナの影響うけて いろいろな言語わめきだすやつだろうwっっっっっっっっっっっっっっっw
914デフォルトの名無しさん:2011/02/18(金) 16:25:07
>>909
Sequenceの代わりにIOArrayを使い、全体を StateT UM IO みたいなモナドにして、手続き的に処理するようにすれば改善するじゃないかと思う。
Haskellで手続き的にするのはどうなのよ、という気もするし、場合によっては性能が悪化すると思うけど、おそらく出題が手続きを前提としているので、この場合は改善するんじゃないかな。
915909:2011/02/18(金) 18:17:37
>>914
ありがとうございます。
それだと確かにSequence.update使ってる辺りが軽くなりそうですね。
ただ、parseInstはそれだと変わらない気がします。
(というかparseInstみたいな単純な関数がどうしてこんなメモリ食うのかわからないです)
916デフォルトの名無しさん:2011/02/18(金) 18:30:05
Word32のかわりにWord#を使ってそれに関連する関数をPrimOpにし
Instの各フィールドを!付きのstrictなものにするとか?
917Perl忍者 ◆M5ZWRnXOj6 :2011/02/18(金) 19:42:25
ひゅひゅだよ

晩御飯の時間だよ
918909:2011/02/18(金) 20:46:12
#haskellで質問してきます。

>>916
ありがとうございます。
Word#がよくわからなかったのでとりあえずInstの全フィールドをstrictにしましたが
多分何も変わってない感じです。
919デフォルトの名無しさん:2011/02/18(金) 21:14:40
Perl忍者の初出はPart12?
920Perl忍者 ◆M5ZWRnXOj6 :2011/02/18(金) 21:18:33
わかんないひゅひゅだよ
921デフォルトの名無しさん:2011/02/18(金) 23:48:10
俺メモ replicate 1が(:[])でいけることを知った
scanl(\a->(++)a.(:[]))[][1..9]
922918:2011/02/19(土) 00:02:41
#haskellで質問して教えて貰ったところ、かなり状況が改善しました。
Before: 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もありかもと言われました。
更新速度は当然落ちるみたいですが。

プログラム自体は正常動作しているのか不明ですがメモリ使用量は改善しました。
ありがとうございました。
923みなみな ◆dEQBXko0pE :2011/02/19(土) 09:00:17
ひゅひゅだよ
924デフォルトの名無しさん:2011/02/19(土) 15:52:34
>>922
その方法で改善する理由も教えてもらった?
925Perl忍者 ◆M5ZWRnXOj6 :2011/02/19(土) 19:16:26
つわぶきっていうキチガイいますかぁ!?

Tsuwabuki「僕は、Catalystやってますよ wiki程度ならつくれますが」
俺「へぇ〜wwすごいねえwすごいよw そうなんだあw」
Tsuwabuki「DBIとかわかりますよ」
俺「ほ〜wすごいねえ まじ?w haskellやってるのにPerlもできるんだねえw」

とか話きいてたやったけどさあwwwwwwwwwwwwwww
こいつカスだよwwwwCatalystとかわめいててwwww
そしたら俺を上から目線でみてきて、連絡こなくなったしさww


自分のほうがレベル高かったからおちょくってやったよ
926Perl忍者 ◆M5ZWRnXOj6 :2011/02/19(土) 19:17:43
ここにスカイプID晒してからさwww

Tsuwabukiから連絡きたんだよwwwwwタイミング的にあれだしw

ハンネぐぐったらhaskellやってるとかツイッターでてきたしさw

ここ見てるやつはTsuwabuki確定だよwwww
927デフォルトの名無しさん:2011/02/19(土) 19:21:30
a->m bによく遭遇するので、こういうの考えてみた
使い分けは
モナド適用前: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)]
928Perl忍者 ◆M5ZWRnXOj6 :2011/02/19(土) 19:29:13
モナドとかいみわからねえからさ
やめちまえ

論理家きどってんじゃねえぞかす
929918:2011/02/19(土) 20:07:29.55
UArrayにしたらメモリ消費量がさらに大幅に減ってアクセスが速くなったのはいいけど予想通り今度は更新が遅い。
IOVector(Unboxed)+unsafeRead,unsafeWrite等にしたらメモリ消費量も少なくアクセス、更新共に速い。
(ただしIOモナドだらけに。そしてモナド内でのwriteがなんか気持ち悪い。)
データ構造の選び方次第でも全く速度やメモリ消費が違うんですね。
無視できない差です。

>>922
ききませんでした。
930デフォルトの名無しさん:2011/02/19(土) 20:07:35.11
はいはい、自分の頭の悪いのひがんでもしようがないでしょ?
931デフォルトの名無しさん:2011/02/19(土) 21:28:06.07
更新の速度を重視するとなると結局IO, unsafe地獄は避けられないのかションボリ
最近発表されたhashing-based containerのスライドでも更新時のArrayのコピーが他の改善点をぶち壊すぐらいのネックになってたし
この辺に関して堅牢さを保ったまま速度を出す方法とかあんのかな?
Haskellの型システムの中で線形型システムを作ってそれでIO地獄を隠蔽するとかぐらい?
bound checkに関してはそれこそstatic contractionとかdependently typeみたいなformal method方面のやりかたを導入するしか無さそう
932デフォルトの名無しさん:2011/02/19(土) 21:55:47.35
IOなしで配列の破壊的更新をしたいならSTArray/STUArrayがあるよ
線形型で実現された配列と比べたら柔軟さで劣るけどHaskellの型システムの枠内ですぐに使える

Arrayのコピーは単純にGHCのrtsのチューニングでなんとかなるんじゃないかと期待
933デフォルトの名無しさん:2011/02/19(土) 21:56:43.03
プリミティブだからrtsのチューニングじゃなくてGHC本体か
934デフォルトの名無しさん:2011/02/20(日) 03:10:56.66
>>929
UArray は、たぶん更新ごとに配列全体をコピーしていると思うので、そりゃ、遅い。
優良生産者、優良消費者でうまく組み合わせていれば、最適化されるかもしれないけど。

この点については、オレはまだ試してないけど、http://itpro.nikkeibp.co.jp/article/COLUMN/20101013/352848/?ST=ittrend で紹介されている手法が、うまく動くかもしれない。

ただ、>>909 の課題自体、手続的な概念によっているんじゃない?
そうであれば、性能関係なく、IOモナドを含むStateモナド系で状態を隠蔽するのが、概念的にもスマートなプログラミングなのではないか、という気がする。
935デフォルトの名無しさん:2011/02/20(日) 10:32:47.06
速さが必要な部分はC++で作って
Haskellから呼び出すってできないの?
936デフォルトの名無しさん:2011/02/20(日) 11:20:26.15
>>935
呼び出すだけなら簡単にできる

双方のメモリアドレスの受け渡しが絡んでくると、扱いが面倒になるが
937デフォルトの名無しさん:2011/02/24(木) 19:48:57.42
haskell始めてみたけどやっぱモナド辛いわ

test = 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 とした結果もどうしてこうなるのか?という感じで…
938デフォルトの名無しさん:2011/02/24(木) 20:30:46.27
そのまま書き換えるとこうかな
test3=[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]
939デフォルトの名無しさん:2011/02/24(木) 21:08:50.21
>>937
> そもそも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
940デフォルトの名無しさん:2011/02/24(木) 22:16:47.71
>>937
オレはリストモナドを平行世界的に理解している。

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
941940:2011/02/24(木) 22:23:42.21
うわ、途中送信しちまった。

test = 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}・・・ などの世界が生き残っている

いちめん染める花は♪ 空へと昇る光♪
幾億の息吹たち♪ 今♪ 世界が生まれ変わる〜♪
942デフォルトの名無しさん:2011/02/24(木) 23:57:02.76
ここは、遥か天空を超えた天界

gfxが一瞬で倒せる領域、もう神の世界

君たちHaskellは、天界から下界を見て広大な心で迎え入れているのだろう
943デフォルトの名無しさん:2011/02/24(木) 23:58:18.26
HaskellのクソザコTsuwabukiでもgfxを瞬殺プログラミングできるレベルなんだろ?
944デフォルトの名無しさん:2011/02/25(金) 00:11:34.58
Haskellの凄さはわかったよ

君たちは、ハスクカルド天界、モナド聖騎士団っていう登場キャラで出してあげるから

おとなしくしてね
945デフォルトの名無しさん:2011/02/25(金) 00:24:00.51
ContTって内側に入れるのと外側から包むのとどっちが早いの?
946937:2011/02/25(金) 01:01:24.13
ああListモナドの>>ってそういう!
皆さんありがとうございます。
色んな方から視点を貰えて助かりました。
なんとか全て理解できた気がします。
後は慣れじゃー
947デフォルトの名無しさん:2011/02/25(金) 07:51:46.59
リストモナドってなんか論理言語っぽいな
948デフォルトの名無しさん:2011/02/25(金) 11:01:13.14
Haskellが今ひとつ流行らないのは、バイナリに後方互換性がないから
949デフォルトの名無しさん:2011/02/25(金) 11:31:34.42
要因はそれ以外にもあるのは当然として、それの占める割合そのものも小さいとおも
950デフォルトの名無しさん:2011/02/25(金) 15:24:18.70
>>947
条件を満たすすべての組み合わせを列挙する、ということが自然に表現できるよね。

>>948
Linuxのディストリビューションとかだと、その辺はパッケージャーが考えること、という気もする。
ただ、実際には、UbuntuのGHCパッケージの放置されっぷりといったら・・・
他のディストリビューションだとどうなのかは知らん。
951デフォルトの名無しさん:2011/02/25(金) 16:08:33.06
2人が延々と自演を繰り返してる恐ろしいスレ
952デフォルトの名無しさん:2011/02/25(金) 16:35:34.38
>>949
大規模な開発だとライブラリの後方互換性は重要な問題だと思うけど

>>950
言語(コンパイラ)仕様がディストリだのパッケージメンテナだのといった存在に依存してるのはおかしいと思う

せっかくネイティブコード吐けるのに、
I/Fを弄らずにライブラリを改変してもバイナリコンパチが崩れるのは、言語として幅を狭めているのでは
953デフォルトの名無しさん:2011/02/25(金) 19:09:31.16
>>746でも書いたけどトレードオフだよ
Haskellはある程度激しい最適化をしないと使い物にならないことが多いから、
バイナリ互換性を崩してパッケージ間インライン化を取るのは仕方ない取引だと思う
954デフォルトの名無しさん:2011/02/25(金) 19:58:48.79
Haskell の最適化って GHC に限ればバイナリ レベルのものは GCC に丸投げなのでは?
激しい最適化はストリームフュージョンとかの中間言語レベルの時だと思うんだが

まぁ、中間言語のファイルをやりとりすることは無く、
実質バイナリ互換性を崩してるという話はその通りなので >>953 には同意する
955デフォルトの名無しさん:2011/02/25(金) 20:45:58.12
でも「このパッケージの関数はインライン展開しなくていいから代わりにバイナリ互換性をよこせ」
みたいなオプションは有り得るよな
956デフォルトの名無しさん:2011/02/25(金) 22:29:11.60
だね
それから、モジュール中の全ての演算に無条件に正確性を強制するオプションがあってもいい。
957デフォルトの名無しさん:2011/02/28(月) 00:53:10.20
すみません
さっき、Haskell Platform の最新版をインストールしたんですが、
Text.Regex.Posix の (=~) の [String] ってなくなったんでしょうか?

↓ みたいなのができなくなってました
"test" =~ "t" :: [String]

Windows7 64ビットです
958デフォルトの名無しさん:2011/02/28(月) 01:46:22.12
>>957
regex-posixパッケージを本格的に使ったことないけど、最新の0.94.4ではダメみたいね。

想像するに
getAllTextMatches $ "test" =~ "t" :: [String]
にとって代わられたのかしら。
959デフォルトの名無しさん:2011/02/28(月) 02:03:23.98
今までfoldrが末尾再帰だと思ってた
偽りの人生だった
960デフォルトの名無しさん:2011/02/28(月) 02:38:48.74
>>959
ワロタ
「偽りの人生」が再帰でないことを祈る
961デフォルトの名無しさん:2011/03/02(水) 07:20:26.91
cabal で gtk2hs-buildtools をインストールしてから、
cabal info gtk2hs-buildtools で確認したところ、

Latest version available: 0.12.0
Latest version installed: [ Unknown ]

と表示されたのですが、これは正しくインストールされたのでしょうか。

未インストールの状態なら、普通は [ Not installed ] と表示されると思うのですが、
[ Unknown ] はどのような状態なのでしょうか。
962デフォルトの名無しさん:2011/03/02(水) 07:35:59.51
>>961
gtk2hsC2hs、gtk2hsHookGenerator、gtk2hsTypeGenっていう三つのコマンドが入っていれば、インストールされているんじゃないの?
963デフォルトの名無しさん:2011/03/02(水) 08:01:34.32
Haskellwikiの
qsort [] = []
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)
として大丈夫ですよね?
964デフォルトの名無しさん:2011/03/02(水) 08:15:23.44
>>963
入力リストの要素に重複がないなら同じだと思うけど、前者はそれがある場合に備えているわけで、べつに冗長ではないのでは?
965デフォルトの名無しさん:2011/03/02(水) 08:24:50.94
なるほど、こう書いてしまうとまずいですね
List.nub+qsortを混ぜたような処理になるわけか
966デフォルトの名無しさん:2011/03/02(水) 08:30:45.27
あれ、訂正。そうはならないけど、中途半端なバグありコードになってしまいますね
ありがとうございました
967デフォルトの名無しさん:2011/03/02(水) 12:43:09.98
同値性テストに冗長性を感じたのに、
filter で2回もリストを辿ることに冗長性は感じないのかな
968デフォルトの名無しさん:2011/03/02(水) 20:59:11.07
先生宿題のクイックソートができました
q[]=[]
q(x:xs)=arr (List.partition(<x))>>>first q >>> second q>>>arr((((((((((((((app .).).(&&&))(((app .).).(&&&)) (const id)).).).).)((flip.).) ((.).((.).))) .).).).) (((.).(.)).)flip(++)(:) x snd fst ) $ xs
969デフォルトの名無しさん:2011/03/02(水) 21:02:26.75
やめろばか
970デフォルトの名無しさん:2011/03/02(水) 21:07:12.68
>>968
テラワロスwww
どれくらい時間かかった?
971デフォルトの名無しさん:2011/03/02(水) 21:10:05.55
>>968
やだ変態っ!
972デフォルトの名無しさん:2011/03/02(水) 21:27:24.31
1時間ぐらいかかりました
973デフォルトの名無しさん:2011/03/02(水) 21:31:20.54
>>972
1時間もアロー、アローでゴシゴシやってたのかwww
オマエみたいな変態は大好きだwww







研究室にはいらない。
974デフォルトの名無しさん:2011/03/02(水) 22:45:38.88
どうしよう、まず読む気がおきないwww
975デフォルトの名無しさん:2011/03/02(水) 22:50:12.88
>>968
お前、墓碑銘それにしなよ
976デフォルトの名無しさん:2011/03/03(木) 06:33:18.64
pointfree先生の力を借りて今必殺の

if' 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)))
977デフォルトの名無しさん:2011/03/03(木) 23:40:57.17
読みにくい
保守しにくい
教育しにくい

絶対に純粋さが裏目に出てる
978デフォルトの名無しさん:2011/03/04(金) 00:06:14.65
1行で150文字超えるとか… もうアホとしか…
979デフォルトの名無しさん:2011/03/04(金) 00:28:00.71
最近Haskell勉強し始めたLisperだけど、>>968を見てHaskellは色々凄いと思いました。
980デフォルトの名無しさん:2011/03/04(金) 07:42:12.40
パズル的な遊びに対してマジレスしなくても・・・
981デフォルトの名無しさん:2011/03/04(金) 17:59:55.90
遊びじゃなくて、オーソドックスにアロースタイルで実装すると >>968 になるんじゃないの?
982デフォルトの名無しさん:2011/03/04(金) 18:06:31.10
クイックソートをアローで表現しようとすること自体が遊びだと思うが
983デフォルトの名無しさん:2011/03/04(金) 21:04:50.35
次、haskell自体〜とか禁止だから!!
984デフォルトの名無しさん:2011/03/05(土) 19:23:50.93
邪悪なCコードの主催者がこの辺うろついてたの見かけたが
誰かなんかしたのか?
985デフォルトの名無しさん:2011/03/05(土) 22:18:14.15
Lazy K コミュニティに行きたかったのに、なぜか勘違いして来ちゃったみたい。
986デフォルトの名無しさん:2011/03/06(日) 08:17:42.16
諸君、議論し給え
987デフォルトの名無しさん:2011/03/06(日) 10:41:43.33
議論っても、ネタがないことには。
じゃぁ、mapはListの(a->b)->[a]->[b]であるべきか、それともfmapの異名としてFunctor f=> (a->b)->f a->f bにしてしまうべきか。
988デフォルトの名無しさん:2011/03/06(日) 10:49:09.37
mapとfmapは別物であるべき派かな俺は
989デフォルトの名無しさん:2011/03/06(日) 12:26:36.46
>>988 なんで?

俺は map の型を Functor f=> (a->b)->f a->f b にして、
全部これで統一して(fmap 要らん)たら良かったと思う

分ける事で構文的にあるいは意味論的に美しくなるとも思えないから、
2つもあるのは冗長にしか感じない
であれば、fmap なんて一般的じゃない名前より map に統一してほしい

まぁ今更もう遅すぎるが
990デフォルトの名無しさん:2011/03/06(日) 12:45:35.95
fmapにはmonomorphism restrictionがあるんじゃないか
991デフォルトの名無しさん:2011/03/06(日) 12:59:23.13
fmapは一般的すぎて読み手に与える情報が少ない
(:[])をreturnと書くのと同種の趣味の悪さを感じる

fmapという名前が気に食わないなら(<$>)という素晴らしい名前があるよ
(<$>)をPreludeに入れるべきという提案なら賛成する
992デフォルトの名無しさん:2011/03/06(日) 13:25:36.32
fmapは関手の射関数という意味だ。Functorクラスを特徴付けるにあたって
対象関数と射関数が必要だからfmapは必要だと思う。
無いとしたらどうやってFunctorクラスを特徴付ける?
993デフォルトの名無しさん:2011/03/06(日) 13:29:57.20
>>992
989が言っているのは、リスト専用のmapは廃止し、Funtorのfmapをmapに改名して、リストの場合も後者を使えばよい、ってことでしょ。
994デフォルトの名無しさん:2011/03/06(日) 13:33:44.07
そういうこと


あと、新スレ立てといた
http://hibari.2ch.net/test/read.cgi/tech/1299385928/
995994:2011/03/06(日) 13:37:55.32
関連スレのリストって要るか?
リンク先が落ちてないか調べるの面倒なんだが
996デフォルトの名無しさん:2011/03/06(日) 13:41:25.90
>>993
スマソ。そういうことか。
997デフォルトの名無しさん:2011/03/06(日) 13:45:10.46
Haskell脳ができあがった人であれば、fmapだけあればmapはイラネって考えるのは分かるけど、
そうでない初心者がいきなりfmapを使いこなすのは(mapと比べて)難しいんじゃないかと。
Haskellへの門戸を大きく開く意味で、現状の命名法は悪くないと思うんだけどな。
998デフォルトの名無しさん:2011/03/06(日) 13:58:44.78
>>998
であれば、

map :: Functor f=> (a->b)->f a->f b

lispMap :: (a->b) -> [a] -> [b]
lispMap = map

こんな感じでいいんじゃないか?

listMap は map をリストの型に特殊化したものなんだけど、
とりあえずはそんな深く考えずに、リストでは listMap を使っておいてね
あとで Functor の意味が分ってきたら汎用性のある map を使っていこう

と言っておけば
999デフォルトの名無しさん:2011/03/06(日) 14:11:29.55
>>995
テンプレが肥大化したスレの場合、どっかのフリーなwikiにページを作って
アウトソーシングしたりしてるのをたまに見かける。
1000デフォルトの名無しさん:2011/03/06(日) 14:36:45.83
>>998
関数定義の内容はどうでも良くて(初心者は関数を使いこなすのが精一杯だから)、
関数の命名法、名前の付け方を言ってるんだけどな。
初心者の常識にズレが少ない、配慮(心配り)という意味で。

少なくともリストというデータ構造は関数型言語の基本であり、ありふれて利用されている。
だからそんなリスト向けにはmapという命名を、理論的には汎用性があっても
初心者には難解な関手向けにはFunctor mapという命名にするのは悪くはないんじゃね。
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。