1 :デフォルトの名無しさん2010/10/10(日) 19:34:34
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
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じゃないけど、勉強になった。
サンクス。
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抜きました
本人確認
24 :デフォルトの名無しさん2010/10/18(月) 21:13:33
>>20-23自作自演な気がする。。。 
25 :Perl忍者 ◆M5ZWRnXOj6 2010/10/18(月) 23:56:01
20~24はHaskell板にふさわしくない書き込みですね

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

そう思いますよね???
27 :Perl忍者 ◆M5ZWRnXOj6 2010/10/19(火) 09:33:28
JPA公認企業の20台後半〜50台くらいのやつが消滅したらPerlerの大半が消える
28 :Perl忍者 ◆M5ZWRnXOj6 2010/10/19(火) 09:38:45
Perlerってモダンの書き方しってるやつな

くそみてええなのは含まれません!
29 :デフォルトの名無しさん2010/10/19(火) 10:06:10
>>28
モダンってどんな書き方?
33 :Perl忍者 ◆M5ZWRnXOj6 2010/10/20(水) 11:31:10
FPS勝負しないか?
haskellじゃねーぞ
プログラマと1回 FPSをやってみたいんだけど
お前らができるFPSをいってくれ 俺はそれをダウンロードしてスタンバイするので
37 :Perl忍者 ◆M5ZWRnXOj6 2010/10/20(水) 12:24:26
doom知ってんぞ体験版?
はやくURLはれ
43 :デフォルトの名無しさん2010/10/20(水) 22:52:52
44 :Perl忍者 ◆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. がどのようなものかを知れば、モナドが見えてくるよ。
52 :デフォルトの名無しさん2010/10/21(木) 09:07:49
モナドの目的は、本来の目的を情報隠蔽することだと思います。
問題は、隠蔽するやり方が何通りもあったために、かえって偶有的属性が増えてしまった
ということだと思います。
53 :492010/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
この世は主観で出来ているのですよ。
あなたはこの世界を五感と知性によって認識しているでしょう。
58 :Perl忍者 ◆M5ZWRnXOj6 2010/10/21(木) 23:44:59
お笑いブームの影響で
おもしろいの基準あがってるからしょうがねえんだよかす
59 :デフォルトの名無しさん2010/10/21(木) 23:47:18
>49
オブジェクト(≒集合の元)を「モナド」と呼んでる段階で眉に唾をつけたくなる.
60 :Perl忍者 ◆M5ZWRnXOj6 2010/10/21(木) 23:49:01
>>57
てめえ
うちはイタチの真似してんだろこら

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

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

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

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

ちょっと前に Haskell 勉強しはじめた者も Haskell に関しては同じ立場だから、
「モナドは**という演算ができて、##という性質があるよ」
の**と##をまず調べたらどうかと言いたかった。
それはモナドの理解のほんの一部だけだけど、
それだけでも Haskell の学習を進めるのには十分だから。
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
モナドの一つの側面は
一度その型で始めたら途中変更は利きませんからね
って事ですかね
68 :492010/10/22(金) 12:39:49
>>64
演算はモナドどうしではなかったと >>53 で訂正したぞ
(>>=、>> の右辺はモナドじゃないから)


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

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

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

自分が知りたいんだと素直に言ったら?
72 :デフォルトの名無しさん2010/10/22(金) 13:02:52
世界は人の主観の産物なのだから本質は「無」なのだ、というわけ。
77 :デフォルトの名無しさん2010/10/22(金) 19:53:05
とりあえず主観は悪くないとしても
他人の主観に便乗するやつはゴミ
78 :デフォルトの名無しさん2010/10/22(金) 20:10:37
>>77
という主観ですね
82 :デフォルトの名無しさん2010/10/22(金) 20:53:23
>>66
そんな側面はありません
84 :Perl忍者 ◆M5ZWRnXOj6 2010/10/22(金) 23:22:49
うけるwwwwwwww
一瞬ここのスレみたら

仏教スレになってた
テラワロスwwwww
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は?
93 :デフォルトの名無しさん2010/10/24(日) 20:33:13
>>90
少なくとも嫌ってる人は少ないだろうな
大半は「好き」「はぁ?何それ」 のどちらかだろ
96 :デフォルトの名無しさん2010/10/25(月) 12:13:28
10スレ前ぐらいで虐められた奴がまだ粘着しているって感じやね
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クラスとしての働きもまったく同じはず。
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と(>>=)で操作する限りにおいては」リストを不自由にしたものに過ぎないと言えるけど、
値を取り出すことやその他の操作を考えれば劣化じゃないし、もちろんコーディング上の役割は違う
111 :100, 1032010/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に置き換えると危険である

・「コンパイルできたら安全」とは限らない
ここからの議論を期待します
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でオブジェクト指向でプログラミングしないでください。
119 :デフォルトの名無しさん2010/10/30(土) 14:45:04
QuickCheck の orderedList 関数は、説明には
与えられた長さの順序リスト生成器を生成するようなことが書かれていますが、
vector 関数のような引数は無いですよね。

どうやって長さを指定するのでしょうか。
resize 関数を作用させるしかないですか?
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
同じ名前で異なるメソッドが呼ばれると嫌がられる気がする
高階関数は良いが、関数のタプルとか関数のリストとかはだめっぽい
126 :デフォルトの名無しさん2010/10/31(日) 23:39:36
>>124
ちょっとまった。 Haskell でもオーバーロードがあるだろ。
127 :デフォルトの名無しさん2010/11/01(月) 00:46:36
>>126
あるね
オーバーロードも嫌がられる場合がある
例えば、MaybeなのかListなのかはっきりしろ、みたいな
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) と書かれていて、
型変数が書かれていないといった旨のエラーだと思います。

このようーな型クラスは作れるのでしょうか。
作れるのなら、どのような方法で作れるでしょうか。
131 :1302010/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の範囲では無理」なら分かるんだが
型システムの表現力を見積もる基準とかってある?
134 :Perl忍者 ◆M5ZWRnXOj6 2010/11/04(木) 17:10:49
Haskellで何作ってんの?
























どうせゴミだろ
135 :100, 1032010/11/04(木) 18:14:26
>>133
とりあえず、Agdaのような「値」を型構築子の引数にとれるものと、
それができないHaskellのようなものの間には、原理的な違いがあると思う。
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は原著しか読んだこと無い
どんなコード?最初の数行だけでもいいから貼ってくれ
あと節の名前(ボイラープレートをなんちゃらとか、グレイスケールファイルとかそういうタイトル)
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)

さてこの説明で分からなかったことに対する質問をどうぞ
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)
156 :デフォルトの名無しさん2010/11/09(火) 20:30:15
getStdRandom の引数が 関数 StdGen->(数値, StdGen)で、
randomR (数値, 数値) の結果が RandomGen->(数値, RandomGen) で、
StdGenがRandomGen のインスタンスだから問題ない、と
StdGen以外でもRandomGenのインスタンスを用意すればいい、と

twoBadRandomsの中に random が説明もなく出てきたんですけど、これは何でしょうか?
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 ページまで理解できたのなら凄いですね
162 :Perl忍者 ◆V8M/4amdko 2010/11/10(水) 17:13:35
ここみてると毎日無駄な事やっててかわいそうに思えてくる

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

役に立つことしかやる余裕がない人は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
175 :Perl忍者 ◆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
忍者がどのような仕事か知らない人がいるみたいだね
185 :デフォルトの名無しさん2010/11/11(木) 19:37:44
189 :Perl忍者 ◆M5ZWRnXOj6 2010/11/11(木) 20:08:03
残念ながら俺には5名
影武者がいる
全て共有してるからな 俺を潰したければ本物を見つけてみろ
191 :デフォルトの名無しさん2010/11/11(木) 20:47:19
>>169
じゃあ九割五分までが底辺だな。w
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
197 :デフォルトの名無しさん2010/11/11(木) 22:06:30
199 :Perl忍者 ◆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
>>200
>>197
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
素っ気ないな

でも、ありがと
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じゃないのが来るようなら自前で判断するコード書く必要がある
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 から落とせるが?
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
忘れてました。

紹介、ありがとうございました。
235 :デフォルトの名無しさん2010/11/17(水) 05:46:15
学ぶのも大変なのに,性能までゴミだと?
そんなクズみたいな言語は使いたくありません.
http://shootout.alioth.debian.org/
236 :デフォルトの名無しさん2010/11/17(水) 06:28:35
実は俺どうこのベンチを解釈したらいいかよくわかんないんだけど
リンク貼っとけば勝手に話を膨らませてくれるだろう

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

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

死んだ方が良いよ

親がかわいそう
242 :デフォルトの名無しさん2010/11/17(水) 23:55:10
まさか息子が忍者やってるとは思いもしないだろうなw
244 :Perl忍者 ◆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高速化したあの少年連れて来い!
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の書評ください
263 :Perl忍者 ◆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の村って進化論禁止してそう
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
忍者はスルーで”カルト”には反応しちゃうんだ....
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
それは、書籍なんかでもよく取り上げられるトピックなんだが、
同じ関数を同じ引数値に適用しても、そのつど評価されるんだよ。
同じ引数値だからキャッシングされてるだろうと考えてはいけない。
それはプログラマ自身がキャッシングの仕組みを作る必要があるんだよ。

一般になんていう名前のテクニックだったかな、忘れてしまった。
キャッシングじゃなくて、もっと別の名前があったような気がしたが。
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 の処理速度を測れたと考えていい?
298 :100, 1032010/11/29(月) 01:57:28
オレは、>>296とは別人物ね。

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

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

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

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変換という最適化がかかるから
すぐ捨てるような中間データは排除してくれることが多い
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 の中身を辿っていった先が定数になっていれば、
最適化がちゃんと働いたということですね。
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に回収されたら終了
311 :3092010/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
そうだよ
318 :3122010/12/06(月) 16:59:21
>>313,314
ありがとうございます。ひとまず腑に落ちました。

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

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

>>312
の例だとmap一発ですが、二発三発なめる場合は
合成を使った方がいいようにも見えます。
321 :デフォルトの名無しさん2010/12/06(月) 20:04:50
どれでも普通に読めるので統一されてなくても気にならないけど、一応俺のスタイルはこんな感じ
- 括弧の代わりに$を使えるならなるべく使う
- 複数行にわたる括弧を消せるときは必ず使う
- 見た目の対称性のために$を使わないことがある(「mappend (f x) (g y)」みたいな場合 )
- 必要のない$は使わない(例えば「f $ g $ x」の右側の$)
- $の左辺に関数合成を置かない(例えば「f . g $ x」)
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)
329 :3262010/12/07(火) 13:14:04
>>328
あぁぁ、フィールドラベルっていうのはそんなふうに使うのですね。
よくわかりました。ありがとう。
330 :デフォルトの名無しさん2010/12/07(火) 14:28:28
>>327
大変おもしろく読んだけれど、ここは気にいらない。
>その前にそもそも番号指定版だけで済ませられないか
常に要求された通り、または、心に浮かんだ通り、
定義するのが基本だと思う。
331 :3272010/12/07(火) 18:11:06
>>330
そりゃ考え方は人それぞれだ。

ひとの考え方と自分の考え方の何がどのように違うのか、
何故違うのか、互いの色んなケースでのメリット・デメリットは何か、
色々比較した上でそっちの方がいいと思うのならそれでいいんじゃないか。
332 :3272010/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
状況というよりスタイルじゃないか?
どの状況でどれを使っても大差ないよ
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
長い式を書くときに、左から書いていける人か、右から書いちゃう人かで違うとか
344 :3422010/12/08(水) 07:56:31
そういう私もポイントフリーを多用してるけど、
それは初めからポイントフリーで考えている時だけ。

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

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

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

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

そういう修行wを通じて、段々と「自然にポイントフリーで考え」られる脳味噌が
できていくんじゃないかな。っつか、俺の場合はそう。
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 は将来、過去を振り返って、いろんな意味で恥ずかしく思うんだろうなぁ
362 :3592010/12/10(金) 05:30:23
>>360
一時の恥で済ませてくれて感謝している
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 プログラムの至る所で役に立つ。
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
それを、一言でいうと「数学と同じ」だと思うんだよね。だから、誰もわざわざ指摘しないというか。
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 ブログラムのネタを振ってくれ

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

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

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

っていうかそれHaskellの本質ってより、ただ高階関数と条件分岐を
組み合わせただけなんじゃ...?
396 :3952010/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作ったけど需要ある?
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
数学者にマルチパラダイムを与えるのは、ボクサーから拳を奪うようなものだ
404 :3952010/12/12(日) 15:04:45
>>400
ふーん。やっぱり何かおかしいと思うよ。わかりやすくするために例を挙げるのに、
座標変換やらなんやらが出てくるのか。

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

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

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

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

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

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

少なくとも「時間を「空間に」」の言い方は全く良くない。「空間に」変えるのではなく、
時間的な問題を「隠蔽する」、と言う方が正しいと思った。
408 :デフォルトの名無しさん2010/12/12(日) 17:56:06
目的のために使える手段を選ぶんじゃない
手段を使えるようにするのが研究
411 :デフォルトの名無しさん2010/12/12(日) 21:26:38
>>398
ある。断じてある。
413 :3902010/12/13(月) 00:44:43
>>391-392
ありがとうございます。とりあえず対話的に動くところを確認しました。
やっぱり元があまりに手続き的だけに、若干ややこしくはなりそうですね。
あとは出てきた1つ1つの要素を見ていって、詳しく見ていこうと思います。
414 :Perl忍者 ◆M5ZWRnXOj6 2010/12/13(月) 21:21:32
知的ぶってんじゃねえよ
ごみめら
416 :デフォルトの名無しさん2010/12/14(火) 00:21:55
>>413
> やっぱり元があまりに手続き的だけに、若干ややこしくはなりそうですね。

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

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

これは手続き型だろうと、関数型だろうと、どんな言語でも同じではなかろうか。
417 :3902010/12/14(火) 00:58:39
>>416
あー、なるほど。
確かに例外処理含むとややこしくなりますね。納得です。
418 :デフォルトの名無しさん2010/12/14(火) 08:27:17
ghci でコピペすると落ちる脆弱性
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
424 :4202010/12/15(水) 20:41:56
>>421,422
スティーブ・ジョブズ乙
でも、たしかに、HTML5も魅力的。

>>423
やはり、オレが思いつく程度のことは、すでに手を付けている人がいるんだな。
427 :Perl忍者 ◆M5ZWRnXOj6 2010/12/15(水) 22:52:10
お前みたいなゴミよりまともだけどね

てめえみたいなやつは自殺しろ
430 :Perl忍者 ◆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だろうね
てめえは低レベルだからさっさとしね
431 :Perl忍者 ◆M5ZWRnXOj6 2010/12/15(水) 23:41:55
かわいそうだからここらへんにしといてやるか
ごみめら

ここのスレも荒れるしな
432 :デフォルトの名無しさん2010/12/15(水) 23:50:50
正格評価をさせるもっとも基本的
な言語要素がseq a bなのはなぜ
なのでしょうか。force aがあって、
その場で、ただちにaを簡約するとなっ
いれば、seqよりも一般的と思う。
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
にすればいい
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そのものじゃねえか気持ち悪い
445 :デフォルトの名無しさん2010/12/16(木) 23:26:15
>>436
無意識に左から評価すると考えてました。
そのためのseqなのですね。大変よくわかりました。
>>437
ありがとうございます。
表面的な使い方としては、理解できましたが、
seqでの等価表現のところがまだ理解しきれません。

>>442
geekはhaskellに似つかわしくないなぁ。
もっとクールビューティなのがいい。
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)
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
  }

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

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

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

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

イブの日の小さな贈り物でした。
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でも動くんじゃないの?
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が発売されていたらしい。
484 :デフォルトの名無しさん2010/12/25(土) 14:08:52
>>478
今時、組み込みでも300MHzていどは回さないとw
# まぁ、目糞鼻糞だが300MHzでx86-200MHzの倍程度のスピードはでる
486 :デフォルトの名無しさん2010/12/25(土) 16:01:49
リンクにバカほどメモリを喰うのって静的リンクしてることと関係あるの?
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じゃないけど、構造体だけ抽出してスタブ作ってゲッターとかセッターとかの関数を自動生成したことならある
496 :4892010/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のソース
501 :4892010/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;
}
504 :4892010/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でも何でも使えばいい
その中間も当然あり得る
506 :4892010/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モナドを使えばいい。
516 :5132010/12/28(火) 02:16:22
>>514
やはり使い分けですね。ありがとうございます。

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

イワブキちゃん???
526 :Perl忍者 ◆M5ZWRnXOj6 2010/12/29(水) 11:40:50
モナドモナド言いまくって逃げ惑うイワブキをつかんで
壁にガンガンたたきつられたら haskellやめそう(笑)
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になるか変わる、という話になるんですかね
537 :デフォルトの名無しさん2010/12/31(金) 17:18:46
このスレマジで人すくねーよな。
前に釣りリンクここに書いてクリックした人数をカウントしたらたった23人だったよ
539 :デフォルトの名無しさん2010/12/31(金) 17:27:13
ソフトウェアはコピーできるから、人数は関係ない
それがソフトウェアの利点
542 :デフォルトの名無しさん2010/12/31(金) 17:32:44
このスレ開いてるやつ全員が釣りリンク踏むと思ってるとかゆとりか
546 :デフォルトの名無しさん2010/12/31(金) 18:00:08
初心者なので普段の会話についていけなくてほとんどレスしてませんが
一応、新レスある度に見てます
547 :デフォルトの名無しさん2010/12/31(金) 19:13:40
レスの内容よりスレの状態が気になるアホは
まあ再帰定義なわけだが
549 :デフォルトの名無しさん2010/12/31(金) 22:41:01
Perlすら出来ないと告白したPerl忍者は、そもそもマですらない
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
なるほど、ちょうどいいかも

ちょっと作ってみるわ
ありがと
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
解決策を提唱する以前に、問題提起をしっかり形にしてほしい。
565 :デフォルトの名無しさん2011/01/05(水) 17:09:24
Fran のソースコードどこかに落ちてない?

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

仕組みがいまいち分らん
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 でも使ってるのかもね。
580 :5762011/01/10(月) 19:13:34
ごめん。オレが勘違いしていた。
これ、コーディング中(あるいはコーディング直後自動的に)そのコードを実行しているみたいね。

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

;; つづく
583 :5762011/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 のように編集すれば、編集ごとにコンパイルチェックをかけ、それが通れば実行される。
584 :5752011/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 との違いがあるのか、などは後ほどレスします。
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が金になる可能性がでてきたな
603 :デフォルトの名無しさん2011/01/15(土) 00:35:20
Haskellコードならけっこう簡単に Objective-C にトランスレートできるかもしれん
604 :デフォルトの名無しさん2011/01/15(土) 08:28:57
手続き型言語にコンパイルしないと関数型言語は実行できないんじゃないですか?
それとも専用のコンピューターがあれば関数型言語のまま実行できたりするんですか?
手続き型言語と関数型言語は同列に並んでるけど、本当は上下関係じゃないですか?
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パーサのほうがいいのかなとか
思うのですが、いかがでしょうか
今作っているプログラムで、そこでちょっと詰まったもので
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
モナドをプログラマーの使い道的に見ると
コンティニュエーションの連鎖で次のものにいろいろ渡したり計算の前後でゴニョゴニョ処理を紛れ込ませられるって把握しとけば夜露死?
619 :6092011/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 も構文を解析して色を変えられる

構文を解析するほど機能的ではないが、
文の正規表現にマッチした所の色を変える程度でよければ、
(関数のシグネチャを定義する所とか、大文字で始まる識別子とか)
秀丸など他にもたくさんのエディタでできる
625 :6242011/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
遅いのは履歴だけだよ
それも一つ前の履歴を表示する時だけ
ていうか早漏すぎだろ
632 :デフォルトの名無しさん2011/01/17(月) 20:49:31
とくに見当たらんな

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

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

それで実用上問題ないのなら、そういう使い方でも良いと思う
立ち上げ直しても、履歴は消えずに残ってるから
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がうまく入らなくて
設定するのもめんどくさくて
638 :デフォルトの名無しさん2011/01/18(火) 19:56:55
ありがとうございます。
3行まとめて処理ではなくて
1行ごとに処理されて前より便利になって嬉しいんですが
これは何故なんでしょうか
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 がいるのかすぐに分る

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

あくまで、Haskell に慣れ親しんだ者のごく主観的な「楽」です。
658 :6512011/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してコンパイルまでする方法ってないですかね

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に附属する他のモジュール

でできた
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
ソースは読んでほしくないけど、「こんなのできた」って自慢したい
いったいどうすれば…
672 :デフォルトの名無しさん2011/01/26(水) 13:42:22
C言語は納品するときに、ソフトで空白や改行やコメントを抜いたり入れたりして、わざとスパゲッティコードにしてる
Haskellだとそれができないから困る
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なら構文糖を全部展開した中間コード生成できた気がする。
それ使えば難読化も可能じゃないかな
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も打てる。エラーメッセージが出ないのだけが難点か。
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 と続いていくという意味)
688 :デフォルトの名無しさん2011/01/28(金) 23:22:05
>>681
計算の組み立てをするという問題について、モナドは解のひとつだけど、最適解ではない
という話を聞いた

それが本当なら、モナド特化の構文はもうちょっと様子を見た方がいいと思う
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モナドを自分で再実装していじくりまわすのがお勧め。
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
副作用がある特別な値を抽象化したのがモナドで、
副作用がある特別な関数を抽象化したのがアローですよね。
普通の関数合成はアロー合成の代わりにならないのでは?

マイクロソフト ワイヤレス ブルートラック マウス Arc Touch Mouse RVF-00006
マイクロソフト ワイヤレス ブルートラック マウス Arc Touch Mouse RVF-00006