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

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

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

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

過去ログ
関数型プログラミング言語Haskell
Part1 ttp://pc.2ch.net/tech/kako/996/996131288.html
Part2 ttp://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 ttp://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 ttp://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 ttp://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 ttp://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 ttp://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 ttp://pc11.2ch.net/test/read.cgi/tech/1193743693/
Part9 ttp://pc11.2ch.net/test/read.cgi/tech/1211010089/
Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/
Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/
Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/
Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/
Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/
Part15 ttp://hibari.2ch.net/test/read.cgi/tech/1310199414/
Part16 ttp://toro.2ch.net/test/read.cgi/tech/1317958045/
Part17 ttp://toro.2ch.net/test/read.cgi/tech/1325510368/
Part18 ttp://toro.2ch.net/test/read.cgi/tech/1331902463/
0175デフォルトの名無しさん2012/07/07(土) 10:27:10.58
イメージとしてはUIのフレームワークを作っていて、Viewはユーザーがいろんな種類のものを自由に増やしてく。
でUIのフレームワーク側はViewに対してINavigatableとかあとから色々機能拡張をする可能性がある。
ユーザー側はあくまでもView派生であればUIフレームワークに組み込めるけれど拡張のインターフェースを実装しているならば、それに即した動作ができる。
0176デフォルトの名無しさん2012/07/07(土) 10:29:19.80
>>174
自分が質問したいのは>>175のような場合のシチュエーションでいろんなViewがすでに色々作られてる中、別の拡張属性を追加したい場合。
その関数の例で言えば、すべてのViewの実装に新たな拡張属性についての関数を追加しなければとなりませんか?
0177デフォルトの名無しさん2012/07/07(土) 10:36:25.63
それってViewが型クラスの場合、Viewに追加するメソッドに
デフォルト実装があれば良いだけじゃない?
0178デフォルトの名無しさん2012/07/07(土) 10:40:01.95
GUIなら、wxHaskell http://hackage.haskell.org/package/wx-0.12.1.6 の型が参考になるかも。
0179デフォルトの名無しさん2012/07/07(土) 10:40:28.56
拡張なんてただの建前ですよ
IUnknownとかを拡張するより最初から作り直した方が早いってのがC#の本音
0180デフォルトの名無しさん2012/07/07(土) 10:48:06.74
ダウンキャストの欠点っていくつかあると思うんだが、
その一つとして、コードがそこら中分岐だらけになって拡張が難しくなる、ってのがあるじゃん。

代数的データ型もその点全く同様なのに、パラメータ多相と高階関数が組み合わさると、
あれだけの一般性が得られる、てのはちょっと驚きだった。
コンピュータサイエンス舐めたらイカンと思ったね。
0181デフォルトの名無しさん2012/07/07(土) 10:48:53.01
>>173,175,177
既存の View に追加でuser-definedなデータを持たせるうまい(型安全な)やり方はあるか、
という質問であると理解した。
0182デフォルトの名無しさん2012/07/07(土) 11:21:00.58
もし >>181 であってるなら、 wxHaskell の場合、
Attr (Window a) (Maybe INavigatable)
というAttrを作ってやれば実現できそう。 で、INavigatableには何か色々持たせる。

問題はどうやって そのAttrを作るかだけども、方法は分からなかった。
http://hackage.haskell.org/packages/archive/wx/0.12.1.6/doc/html/Graphics-UI-WX-Attributes.html
あるいはwx-coreに手を入れる必要があるかもしれない。

多態性カッコイイ!任意の型を扱えるのカッコイイ!
ってなるのはわかるけど、そんな機能は無くてもやりたい事を実現できるかもよ、と言いたい。
0183デフォルトの名無しさん2012/07/07(土) 12:46:36.80
だとしたらそれはモデリングの問題で
DCI (Data Context Interaction)
とか当たってみた方がよろしんじゃないかしら
0184デフォルトの名無しさん2012/07/07(土) 16:15:12.31
オレも>>181とたぶん同意意見で、フレームワークのユーザープログラマが、
setCallBack :: (View -> IO ()) -> IO () みたいな関数にView -> IO () な関数を渡さないといけないし、
またViewの定義もいじれない、っていうような状況を>>161は想定しているんだと思う。

そういう場合、フレームワーク側で、View じゃなくってView a みたいな型と、
userData :: View a -> a みたいな関数を用意しておくことにするのが簡単な解決かな。

wxHaskellは知らんけど、>>182の説明しているのも、そういう方向性の解決だと思う。
0185デフォルトの名無しさん2012/07/07(土) 18:54:53.76
簡単でいいならHashTableが簡単。
lookup :: HashTable View INavigatable -> View -> IO (Maybe INavigatable)
0186デフォルトの名無しさん2012/07/07(土) 19:07:25.76
haskell的にはHashTableよりも連想リストかMapじゃないの
0187デフォルトの名無しさん2012/07/07(土) 19:49:11.27
>>186
どうしてなの?
0188デフォルトの名無しさん2012/07/08(日) 02:54:54.20
>>187
永続データ構造使った方がいいんじゃないかな
0189デフォルトの名無しさん2012/07/08(日) 08:39:37.66
個人的には同型対応する方がいいから普通の言語と同じ方がいい。
0190デフォルトの名無しさん2012/07/08(日) 08:55:08.51
>>188
すまん、もう少し詳しく。

今回の件でなぜ永続データ構造の方が望ましいのか。
永続データ構造に比べて HashTable だと不利なるケースは何か。
という辺りを。

俺には今回の件で、永続データ構造でも HashTable 使っても、
プログラムの見やすさや効率の点で大して変わらないように思える。

というのも、>>181 の意図であるなら、
永続データ構造を使ってもその値は結局 IO モナドを被せた方が、
プログラムがスッキリするような気がするのだが。
0191デフォルトの名無しさん2012/07/08(日) 09:14:23.10
既存のGUIをFFIで呼ぶならmutableなHashTable使う以外の選択肢はないでしょー

wxFruitみたくFRPっぽく宣言的にするならともかく
0192デフォルトの名無しさん2012/07/08(日) 09:14:49.61
有利不利とは関係ないけど、Data.HashTableはGHC 7.8.1で削除されるそうな。
http://www.haskell.org/pipermail/cvs-libraries/2012-June/015725.html
0193デフォルトの名無しさん2012/07/08(日) 09:20:44.92
wxcoreで wxWidgets のC++の継承関係をHaskellで表現するやり方が面白い
一番親の(C++)クラス EvtHandler は Haskell の EvtHandler a という型で表し
その子クラス Window は EvtHandler (Window a),
さらにその子クラス Frameは EvtHandler (Window (Frame a)) というように
パラメタ多相でうまく(?)エンコードしている

ただ、既存のwxWidgetクラスをHaskellでどうやって継承するのか謎
0194デフォルトの名無しさん2012/07/08(日) 09:33:50.12
既存のC++クラスがObjective-C++/CLIでどんな扱いを受けているか考えれば大体わかる
0195デフォルトの名無しさん2012/07/08(日) 11:39:58.99
例えばData.HashTable.STを使ってね、とある。
http://hackage.haskell.org/package/hashtables/
0196デフォルトの名無しさん2012/07/08(日) 15:40:24.88
>>194
どんな扱いを受けてるの?
0197デフォルトの名無しさん2012/07/08(日) 22:29:03.76
それはそれ、これはこれ
01981762012/07/09(月) 00:43:57.30
ちょっと2ch離れてました。すみません。
自分的には>>177で言われてるデフォルト実装があればコード量の増大はなくなるかなーと納得。

>>181
ちょっとHaskellまだ勉強したてなので結論としてそういうふうに落ち着くのかちょっとわからず。
C++やC#でViewクラスを継承した色々なクラスで、View自体の実装とは関係のない別の性質を持たせたい場合、型クラスを使った時にコードが膨らまないかという意味。余計わかりにくいかもですが。
一つの方法として>>181のような外部から属性を追加するという方法でも実現は出来ると思います。

>>193のやり方を具体的に理解してないですが、自分のイメージに近そうな予感。

いずれにしてもC++/C#的なやり方でなくて、他にうまいやり方がありそうな気が。精進してきます(´・ω・`)
0199デフォルトの名無しさん2012/07/09(月) 01:20:52.64
UIって、自動コーディングできなのだろうか
ロジックとViewを上手に分離したら、Viewの部分は仕様だけ用意すればあとは自動でhsコード出力できないのだろうか

上級者はやってるんだろうな…
0200デフォルトの名無しさん2012/07/09(月) 11:18:53.32
文字実体参照の変換を取り扱うライブラリはありますか?

> ⇔ >
0201デフォルトの名無しさん2012/07/09(月) 20:03:56.84
ParseCじゃ無理なん?
0202デフォルトの名無しさん2012/07/09(月) 22:24:54.08
モナドわけわからん
0203デフォルトの名無しさん2012/07/09(月) 22:44:04.41
モナドの「何が」わけわからん の?
0204デフォルトの名無しさん2012/07/09(月) 23:05:22.23
モナドの利点とされるもののうち、どこまでがモナドの利点で、どこまでが型クラスの利点なのか
ごっちゃになってわけわからん
0205デフォルトの名無しさん2012/07/09(月) 23:09:32.93
機能毎に分割できるというところがモナドの利点
それ以外が型クラス
0206デフォルトの名無しさん2012/07/09(月) 23:11:13.11
つ チラ裏
0207デフォルトの名無しさん2012/07/09(月) 23:23:54.84
>>204
たしかに、わけわからなくなりそうな疑問だな。

不純な計算を形式化/モデル化できることがモナドという代数的構造の利点で、
実装の異なるデータの集合を代数的構造の面で抽象化・一般化してプログラミングできることが型クラスの利点で、
両者あわさって、実装/意味の異なる不純な計算を抽象化・一般化してプログラミングできることが
モナドという型クラスが存在する利点、といってみるテスト
0208デフォルトの名無しさん2012/07/09(月) 23:25:36.01
不純でない計算も形式化できるよ > モナド
0209デフォルトの名無しさん2012/07/10(火) 00:06:37.86
型クラスない言語でモナってるのを見れば?
0210デフォルトの名無しさん2012/07/10(火) 00:35:06.79
簡約を遅延することと、IOを実行しないでおくことの違いを説明してください
0211デフォルトの名無しさん2012/07/10(火) 01:04:20.52
>>210
着眼点がぜんぜん違うから、比較すること自体が困難だな。

例えるなら、ハローワークに行こうと決意するのを先延ばしにするのが簡約の遅延で、決意したけどなかなか行かないのが実行の遅延。
0212デフォルトの名無しさん2012/07/10(火) 01:30:08.39
計算のシーケンスを代数で表現したのがモナド
しかもモナドが必要十分の構造というわけでもない
0213デフォルトの名無しさん2012/07/10(火) 01:58:22.49

簡約は式を評価する時になされることだから、式の値が要求されるまで簡約は遅延される
IOも、その結果が要求されるまで遅延される
どちらも遅延評価の結果 と考えています
0214デフォルトの名無しさん2012/07/10(火) 08:32:24.44
>IOも、その結果が要求されるまで遅延される
ダウト
0215デフォルトの名無しさん2012/07/10(火) 08:58:05.68
>>209
ツボにはまったw
0216デフォルトの名無しさん2012/07/10(火) 11:59:56.17
>>214
それがIOもサンクなんだよな、、、
0217デフォルトの名無しさん2012/07/10(火) 12:02:54.97
Maybeは不純
0218デフォルトの名無しさん2012/07/10(火) 22:11:47.43
純粋(pure)がどうたらこうたらというのはHaskellの存在意義として
重要なだけであって、モナドは関係ない。
計算(computation)もHaskellでは特筆する話ではない。なぜなら計算概念が
一体何のことなのか、いまのところ固まってないため。
モナドの利点は入出力、リスト、継続、環境、状態、例外処理などをそれぞれ
”切り分けることができるようになる”というところだ。
書くコード書くコード全部スパゲッティ化するプログラマでも、モナドの枠組みに合わせるように
コードが書ければ、あら不思議、ちゃんと機能毎に切り分けられます、という理論。

そもそも疑念に思うべきところは、例えばリストモナドはリストのみで完結していて、他のMaybeモナド
には一切影響がないというところだった。これは、よく考えると驚くべきことだ。
0219デフォルトの名無しさん2012/07/10(火) 22:13:05.49
他のMaybeモナドには
じゃなくて
他のMaybeモナド等には
で。
0220デフォルトの名無しさん2012/07/10(火) 22:29:29.28
それ型クラスの利点…
0221デフォルトの名無しさん2012/07/10(火) 22:30:56.35
しばらくモナるわ
0222デフォルトの名無しさん2012/07/10(火) 22:31:18.50
言い訳Maybe
0223デフォルトの名無しさん2012/07/10(火) 22:45:04.56
型クラスがどこからどこまでを指すのかわからないので今は明確に違いは言えない。

とりあえず種本は下記なので、疑わしいならば読め。
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.2885
0224デフォルトの名無しさん2012/07/10(火) 23:24:08.47
先入観があると内容が意味不明に写ると思うのであらすじを書いておくと、
この論文の名前はSemanticLego(意味論的レゴ)という名前で
内容は、表示的意味論は理論としては強力だけれど、実際プログラミング言語を
実装しようと思うと、拡張性が悪すぎてちょっと機能を追加しようと思うと
いままでのコードをかなり書き換える必要があってすごい実用性が低い
ということをSchemeの実例コードを使って示していく。
そののち、モナドという枠組みを使って言語を組むと、拡張性も良くて
意味論的組合せもレゴのように自在に可能であることが示される。
0225デフォルトの名無しさん2012/07/10(火) 23:25:09.93
すまん。推敲が足りなかった。
0226デフォルトの名無しさん2012/07/10(火) 23:56:09.39
モナドを使って意味論定義をモジュラーにする話はよく知っているつもりだけど(一応専門なので)
>218の

> モナドの利点は入出力、リスト、継続、環境、状態、例外処理などをそれぞれ
> ”切り分けることができるようになる”というところだ。
> 書くコード書くコード全部スパゲッティ化するプログラマでも、モナドの枠組みに合わせるように
> コードが書ければ、あら不思議、ちゃんと機能毎に切り分けられます、という理論。

の意味はさっぱりわからない。
0227デフォルトの名無しさん2012/07/11(水) 00:40:05.13
慌てていたので、別のところに投稿してしまって重複投稿になっていますが、
こちらが正しい投稿先です。
----
>>226
そう突っ込まれるとうまく返せん。しばし待て。
とりあえず意図としては、
1行目は個々の機能毎にモジュール化できるということを言っているつもり
2行目は機能毎にモジュール化できるということが具体的にどういうことか
言おうと思って出した例。そんなことができるかはわからない。

とりあえず、自分はこのように理解していて、説明しようとするとこういう風になる。
226が説明しようとするとどうなる?
0228デフォルトの名無しさん2012/07/11(水) 00:43:48.44
そもそもHaskellのモナドって計算理論のモナドなのだろうか?
なんか異和感がある
0229デフォルトの名無しさん2012/07/11(水) 09:02:56.52
日々Haskellでモナニーしてるみなさんおはようございます

mtlの道場的サイトを紹介してください
実例豊富なのがいいです^O^
0230デフォルトの名無しさん2012/07/11(水) 09:16:33.33
>>218だけ見ると構造化プログラミングか何かの話に見えてしまうな
モナドの利点って、今までとは違った観点で切り分けられることだと思うんだけど、うまく説明できない
0231デフォルトの名無しさん2012/07/11(水) 09:38:59.72
んお?モナドって文脈を持ったものを普通の記述でスッキリかけてナイスってことじゃないん?
0232デフォルトの名無しさん2012/07/11(水) 11:31:29.20
文脈ってのも曖昧だしなあ
0233デフォルトの名無しさん2012/07/11(水) 11:41:44.22
自分的にはIOの事忘れてざっくりと"文脈"とくくったほうが理解しやすかった。
ファンクターは普通の関数を文脈持った値に適用する。
アプリカティブは文脈持った値?に文脈持った値を適用する。
モナドは文脈持った処理をくっつける。
0234デフォルトの名無しさん2012/07/11(水) 12:30:54.84
なぜモナドの事を忘れて一般の型クラスを総括しないのかね。
忘れていい事と忘れてはならない事を見分ける方法はあるだろうか。
0235デフォルトの名無しさん2012/07/11(水) 12:34:18.32
>>234
忘れていい事とは何かをちゃんと定義できれば集合は分割できる。

だから見分ける方法はちゃんと定義する事だ。
0236デフォルトの名無しさん2012/07/11(水) 20:16:31.49
悪いがもう話をしたくない。
0237デフォルトの名無しさん2012/07/11(水) 21:27:45.79
Repa でガウスぼかしみたいな畳み込み演算をしたいです。

一次元で言うと、

元データ [x0, x1, x2, x3, x4]
カーネル [k0, k1, k2]

演算 [x0*k0 + x1*k1 + x2*k2, x1*k0 + x2*k1 + x3*k2, x2*k0 + x3*k1 + x4*k2]

こんな感じの演算です。

今は traverse2 関数を使い、いちいち各配列のインデックスを指定して計算していますが、
他にも方法はあるのでしょうか。
02382372012/07/11(水) 21:30:03.63
すいません。

他にもっと効率のいい方法はあるのか、という質問です。
0239デフォルトの名無しさん2012/07/13(金) 22:21:32.07
>>228
一体何でそんな話になる?
分割できて自由に組み合わせできるという以上の話なんてないはずだ。
そもそも計算理論のモナドとはなんのことを指すのか答えろ。

>>234
じゃあお前が総括しろ。
0240デフォルトの名無しさん2012/07/14(土) 00:51:44.58
>>239
そもそもと言ってるのだから、改めてより深いテーマを提起しているのでは?

計算理論のモナドとは何かというのは、私もぜひ聞きたいです。
おそらく圏論のモナドの事を言っていて、
これと Haskell で利用されているモナドとの間の相違点が気になる、
という話ではないかと思うのですが、違いますか?


私には、>>239 がなんで命令形なのかよく分らない。
無駄に波風の原因を作らず、もっと普通に訊けばいいと思うんだけど。
0241デフォルトの名無しさん2012/07/14(土) 06:48:22.16
失礼した。ただ、やはりもうあんたらに形式上でも話をするのはいやだ。
0242デフォルトの名無しさん2012/07/14(土) 06:50:15.15
ということがわかった。
0243デフォルトの名無しさん2012/07/14(土) 08:51:48.20
はあ、そうですか
0244デフォルトの名無しさん2012/07/14(土) 10:30:52.62
Haskellの型クラスはMLのファンクタと同じで、名前空間を入れると名前空間が出てくる
instance Monad Foo where ・・・で名前空間をインプットすると
Monad a => の型をもつ全ての名前がアウトプットされる

ただし、Haskellで演算子オーバーロードを多用するためには名前空間を明示したくない
そこで型推論を改造して名前空間も省略できるようにしたのが型クラスだ
0245デフォルトの名無しさん2012/07/14(土) 10:37:20.23
>>218
”切り分けることができるようになる”というのは名前空間のことを言ってるだけだと思う
0246デフォルトの名無しさん2012/07/14(土) 11:33:45.51
>>223にsemanticsはcomputation ADTとlanguage ADTに分けられるが
computation ADTはmonadとmonad transformer使って切り分けられるからpolymorphicにできると書いてあるよ
型クラスは使い易くするだけ
0247デフォルトの名無しさん2012/07/14(土) 13:16:29.92
>>223のfigure 1.18のように
SemanticLegoではmake-computationsを使ってcomputation ADTの構築を手動で書くが
Haskellは型クラスの仕組みを使って自動的にやらせることができるから便利
ということだろう
0248デフォルトの名無しさん2012/07/14(土) 20:55:40.42
accelerate-cuda パッケージを使ってみた人いますか?

私は今のところ生憎 CUDA 環境がないので、ネット上の CUDA に関する情報や
サンプルコードなどを見て想像するしかないのですが・・・

[1] 全体の使用感はどんな感じなのでしょうか。
処理の速さは感じられますか。

[2] プログラマは CUDA のメモリなどの仕組みは全く、
あるいはほとんど意識する必要が無いのでしょうか。

[3] 実行ファイルにコンパイルしないと CUDA は働かないのでしょうか。
それとも ghci 上でも、Haskell のデフォルトのリストや配列よりも速いでしょうか。

特に [2] の質問でよい応えが得られれば、
ワークステーションクラスのノートPCをひとつ買ってみようと思います。
0249デフォルトの名無しさん2012/07/15(日) 00:59:34.76
名前空間をインプット/アウトプットするという言い方は良くわからないし、あまり見たことも無い
MLのファンクタならそういえなくもないけど
0250デフォルトの名無しさん2012/07/15(日) 01:10:01.92
そもそもなんで >>223 が出てきたのか謎
そういうのを今更じっくり読むくらいならもっとMonadTransなコード書いた方がいいんでないの??

0251デフォルトの名無しさん2012/07/15(日) 03:09:19.01
関数的で高機能な物理エンジンない?
一通り探したけど,どれもc辺りへのbindingで剛体の位置得るだけなのにIO必須で好きじゃない

haskellってこういうのに得意なイメージあったんだがなあ
関数型だと遅くて現実的じゃないのだろうか
0252デフォルトの名無しさん2012/07/15(日) 07:42:18.12
そういう用途で使ってる人が少ないだけじゃね?
0253デフォルトの名無しさん2012/07/15(日) 08:00:53.85
Haskellは型推論が得意
型には物理的実体がない
どちらかと言えば、想定外の型を受け取りたくないという精神的なものを表現するのが得意
0254デフォルトの名無しさん2012/07/15(日) 11:51:37.81
そうじゃなくて、函数プログラミングのパラダイムが物理演算に向いてるかどうかって事じゃねーの
型が精神的ってのも激しく謎だが
0255デフォルトの名無しさん2012/07/15(日) 12:11:20.25
http://hackage.haskell.org/package/Paraiso-0.1.0.0
低レイヤーのエンジンに、合成して突っ込む形のものは向いてるかもしれないね。
0256デフォルトの名無しさん2012/07/15(日) 12:49:38.11
そもそもOpenGLが大々的に紹介されてときは関数型パラダイムだともてはやされてたのに…
0257デフォルトの名無しさん2012/07/15(日) 12:52:25.71
>>251
> haskellってこういうのに得意なイメージあったんだがなあ

どこからそんなイメージが湧いてくるの?

自分で物理演算をちょっと試してみて
「お、結構いけそうかも」って思えたの?
0258デフォルトの名無しさん2012/07/15(日) 13:23:51.38
何年か前までJavaScriptは関数型言語だった
関数型言語の集合は、国境や法律のように時々変わる
0259デフォルトの名無しさん2012/07/15(日) 14:15:14.70
>>257
OpenGLとかもそうだけど、最近の物理演算エンジンはロジックがステートマシンであることを前面に出してるから
その宣伝を鵜呑みにすれば、Haskellが得意なはず
0260デフォルトの名無しさん2012/07/15(日) 14:34:39.22
>>259
話をぶった切って悪いが、丁度よい機会だから訊いてみたい。

Haskell でステートマシンを組む際のよい見本となる解説を教えてほしい。
ネットも書籍も探してみたが、なかなか見当たらない。

ゲームを作ろうと思ってる。
ステージ切り替え、場面切り替えなどでステートマシンを使うと良さそうだが、
どうにも手続き型っぽくなってしまう。
状態を保存したりするのに、どうしても IORef に頼ってしまうんだ。
0261デフォルトの名無しさん2012/07/15(日) 17:43:44.11
その手続きっぽいコードの例をお願い
0262デフォルトの名無しさん2012/07/15(日) 19:56:03.09
>>261
自分のゲームの今のコードは複雑で長く、何より汚いから晒すのは正直恥ずかしい。
だから晒すのは、手続きっぽくて嫌だなぁと思うエッセンスの部分だけね。

簡単に言えば、[タイトル画面シーン] や [オプション画面シーン] などシーン毎に関数を作ってる。
この関数は、戻り値として「次のシーン」を返すようになっていて、
シーン内でプレイヤーが行った行動などによって次のシーンを決定する。

newtype SceneProc = SP (Time -> GamePad -> (ScreenDesc, SceneProc))

titleScene :: GameData -> SceneProc
titleScene gd = SP $ \t gp ->
  let scr = makeScreenDesc -- 画面を構成する指示書を作る
  in case 時間やゲームパッドなどの状態 of
    オプション画面へ遷移するなら -> (scr, optionScene gd)
    とくに何もしていないなら -> (scr, titleScene gd)

optionScene, playScene, gameOverScene・・・ :: GameData -> SceneProc

mainLoop :: SceneProc -> SceneProc
mainLoop (SP scene) = do
  (t, gp) <- 現在時間とゲームパッドの状態
  let (scr, next) = scene t gp
  disp scr -- 画面表示
  mainLoop next

(実際は GameData 型の中で IORef を多用してる。その方が記述がスッキリするから)

で問題は、こういう作りだと、titleScene などの各シーン関数で、
やたら if や case of で場合分けする羽目になるということ。
A なら B、C なら D、A でかつ B なら E などの記述が並んで、
ハッキリ言って、関数型特有の宣言的な記述からはほど遠く見える。
0263デフォルトの名無しさん2012/07/15(日) 19:58:59.40
ごめん、mainLoop は IO ね。

でも雰囲気は分ってもらえると思う。
02642482012/07/15(日) 20:23:42.91
OpenCL パッケージの方でもいいです。
使ってみた方はいるでしょうか。

パフォーマンスはどれほど出るものなのでしょうか。

このパッケージの github にあるサンプルコードを見てみると、
こちらは自分で OpenCL のコードを書かなければならないみたいですが、
DSL タイプの支援ライブラリは無いのでしょうか。
0265デフォルトの名無しさん2012/07/15(日) 21:37:54.99
>>237
いろいろ試しているけど、
あなたが今使っているコードがどういうものか分からないので、
比較ができないぁ

あなたがいま実際に取り組んでいる実際の問題でなくても構わないので、
高速化をしたら比較できるような対象となるお題コードを、
http://ideone.com/ とかにアップしてURIを張り付けてよ
0266デフォルトの名無しさん2012/07/15(日) 22:21:35.02
http://www.geocities.jp/takascience/haskell/monadius_ja.html
monadiusの作り方
02672372012/07/15(日) 23:00:10.71
>>265
http://ideone.com/l7Ina に私のコードを貼り付けました。
そのまま ghci でロードして頂ければサンプルデータで実行できます。

任意長の元データ b とカーネルデータ k (|b| >= |k|)に対して、
>>237 のような演算を行う関数 calc を定義しています。

このコードの (\i -> kp (Z:.i) * bp (Z:.ic+i)) の辺りが何とも間の抜けた感じです。
配列に対してインデックスで要素単体を指定して演算しているのが、
なんていうか Haskell らしくないというか、気持ちが落ち着かないというか・・・

traverse 系関数ではこういうインデックス指定に対して特に最適化して作られていて、
この方法が最も効率がいいというのなら仕方ありませんが、
もっと効率よくて見やすいコードになるのなら嬉しいです。


ちなみに >>237 のような演算は、同じカーネルを対角線に階段状に並べたN重対角行列と、
元データのベクトルとの積の演算なので、hmatrix でやった方が速いかも知れませんね。
明日 hmatrix を入れて実検してみます。
0268デフォルトの名無しさん2012/07/16(月) 00:55:59.93
>>267
http://ideone.com/e6PGR

sumP と *^ を使ってみた。

kernelのsizeを約100、baseのsizeを約10000にして
ベンチマークフレームワーク ceriterion を使って測定してみたら、
15万倍くらいはやくなってる。39.45803 msから256.1315 nsヘ。

・・・マジで?

我ながら信じられないので、 ceriterion の使い方間違っているような気がする。
nsはナノ秒だよね? よね?
0269デフォルトの名無しさん2012/07/16(月) 01:40:46.31
>>262
SceneProcはステートマシンとしては普通の定義だと思う。

>やたら if や case of で場合分けする羽目になるということ。
そういう風に定義する計算モデルなのだから致し方ない。
ステートマシンを状態遷移表で書き下したとき、

・titleSceneやoptionScene等の関数が「状態」
・パターンやガードが「入力」
・その右辺式の値が「出力と遷移」 (ScreenDesc, SceneProc)

に対応していて、ミーリー型オートマトンを定義してる、と考えるといいと思う。
Monadiusの定義だとムーア型かな。
シーンを関数として作る、というのは方向性として間違ってないんじゃないかな。
各シーンの内部状態をさらにどうしてるかが問題だけど。
IORefを多用している事と、ステートマシンが分岐だらけであることとはあまり関連性がない気がする。

とりあえずステートマシンの参考になりそうな、有名所を適当に上げると、、
SceneProcの定義はYampaの定義が一番近いと思う。Netwireも確かこんなん。
これらの単純なモデルは、arrowsパッケージのAutomaton i o。(関数型プログラミングの楽しみ10章の単純オートマトン)

変種としては、
SceneProc r
 = SP (Time -> GamePad -> (ScreenDesc, SceneProc r))
 | Done r
と、Done rを付け加えるとモナドにできて、コルーチンみたいな中断/再開が可能になる。(Done rは受理状態に相当。)
Enumeratorとか、Conduit、Pipes、もこのタイプ。
これらをさらに抽象化したのがmonad-coroutineで、コイツは実はMonadFreeというものに解りやすい名前を付けただけ、
とか色々奥の深い世界があったりする。
MonadFreeの別の応用としてOperationalモナドというのもあったり…。(自動モナド化とか、インタプリタとか興味深かった)

0270デフォルトの名無しさん2012/07/16(月) 02:15:42.25
>>268
演算の中に畳み込みが入ってるなら、配列要素数に比例する以上の速度変化が出てもそれほど不思議じゃない
ただ、ghci環境でやってるなら速度計測はまったくアテにならない
exeファイルを作って計測すべき
0271デフォルトの名無しさん2012/07/16(月) 04:49:51.07
Haskellを擬人化するなら寡黙な女の子だね
言葉を選んで口数少なく
あ、うん……
0272デフォルトの名無しさん2012/07/16(月) 04:51:59.44
>>233
アプリケイティヴって読んでた……:(;゙゚'ω゚'):
0273デフォルトの名無しさん2012/07/16(月) 06:51:33.61
>>271
ちょっとした間違いを見つけると厳しく指摘する神経質な理系女子…

ナンカイヤダ
0274デフォルトの名無しさん2012/07/16(月) 07:43:11.05
Agdaさんと付き合うとHaskellさんぐらいの口うるささは可愛いものだと思えるのでお勧め
■ このスレッドは過去ログ倉庫に格納されています