関数型プログラミング ..
577:デフォルトの名無しさん
08/08/22 22:12:26
>>575
「記号」と言われてもいまいちピンと来ないんだが、何にせよ、
普通の手続き型言語が「記号」を処理するのと大差ない方法で処理してると思う
取り得る種類がコンパイル時に決まっているなら列挙型
そうでないなら整数とか文字列
文字列の比較のコストが問題になるなら自分でシンボルテーブルのようなものを用意する、とか
578:デフォルトの名無しさん
08/08/22 22:34:03
>>576
>>310-314
579:デフォルトの名無しさん
08/08/23 09:45:26
>>572
Prologでも、
1レコード512バイトをsub_atomで30項目に分解したり、更にsplitの
処理をしたりすると確かにアトムが大量発生するだろうが、
Stringとして読み込んで、終始String処理に徹すれば、アルファベットの
数、つまり高々数万のアトムで済むんじゃないの?
Stringすなわちリスト処理になると遅いから嫌なのかな。
580:デフォルトの名無しさん
08/08/23 10:00:27
宣言的言語をリアルタイム処理に使いたくない病にかかってる。
資源が十分にあると理屈では分かっていても、終わったら電源切っても大丈夫な処理じゃないと拒否反応がでる。
581:デフォルトの名無しさん
08/08/23 10:09:14
>>579
処理速度もあるかも知れませんが、アトムだと、
foo([株式会社|R],R).
と書けるところが、Stringだと
foo(List,R) :- append("株式会社",R,List).
と書かなくてはならないということがあります。
appendを高速化する機構が欲しくなりますね。
582:デフォルトの名無しさん
08/08/23 10:35:10
それって代数的データ型を使ってこんな感じで良いんじゃない?
data Atom = Kabushiki | Dummy deriving (Show, Eq)
foo :: [Atom] -> [Atom]
foo (Kabushiki : r) = r
583:デフォルトの名無しさん
08/08/23 11:43:27
Prologでまったり Part3
スレリンク(tech板)
584:デフォルトの名無しさん
08/08/23 12:43:04
>>581
この話おかしいよ。
foo([株式会社|R],R). の方は、
すでに株式会社というアトムが切り出されていて、リストの構成要素になっている。
一方、
foo(List,R) :- append("株式会社",R,List). のListはString。ここは、
foo(["株式会社"|R],R).
でなきゃ、フェアじゃない。
585:デフォルトの名無しさん
08/08/23 13:58:45
>>572
> Prologを事務処理に使うと、住所や氏名情報などで爆発的にアトムが発生し
第五世代コンピュータプロジェクトの成果を是非参照下さい。
586:36 ◆K0BqlCB3.k
08/08/23 14:16:16
>>585
よく知らないけどソフトウェア科学会会誌7月号に第五の話題が載っていたよ
587:デフォルトの名無しさん
08/08/23 14:21:10
成果って、「prologって役立たずじゃん」という結論を得たこと?
588:36 ◆K0BqlCB3.k
08/08/23 14:28:53
>>587
それは短絡的な人たちの根拠のないうわさ。
第五は基礎研究なので企業の人たちが求めるような成果が出ないのは当たり前のこと。
589:デフォルトの名無しさん
08/08/23 14:31:33
Prologの話は他でやってくれ
んで問題点を整理してまたいらっしゃい
590:36 ◆K0BqlCB3.k
08/08/23 14:33:31
詳しいことは忘れたけど、
述語論理による仕様記述を使った鉄道のプロジェクトが企業側で行われた例があったような。
なんだったっけ?
591:デフォルトの名無しさん
08/08/23 14:45:22
Prologはどうでもいいのだが、Haskellで金融(とくに保険業)のアブリを
開発する場合、何か問題になる点はないのか。
592:デフォルトの名無しさん
08/08/23 14:54:20
>>591
必要なメモリサイズを予測しにくい点とか。full lazyな処理系全般に言えると思うけど。
593:デフォルトの名無しさん
08/08/23 14:57:02
金融系システムにHaskellを使うメリット自体が思いうかばん。
いいじゃん、Javaでつくるのが流行ならJavaで作らせれば。
どうせ枯れたシステムなんだから。
594:デフォルトの名無しさん
08/08/23 15:00:18
>>592
full lazyな処理系って、よくわからない。
595:36 ◆K0BqlCB3.k
08/08/23 15:11:43
どんな言語で書いたとしても、必要なメモリの量は実際に動かしてみないとわからないよ。
596:デフォルトの名無しさん
08/08/23 15:17:46
haskellっていいプロファイラあんの?
597:デフォルトの名無しさん
08/08/23 15:26:42
>>595
COBOLなんかは確定してると思うけど。
598:デフォルトの名無しさん
08/08/23 15:42:16
>>597
してない。
SORTなどに内部的に使う記憶容量が不明。
599:デフォルトの名無しさん
08/08/23 15:43:11
Haskellのようにデフォルトで遅延評価する言語は、
計算をできるかぎり遅延させようとするから、
下手な書き方するとすぐメモリリークする
Haskellのメモリリークは大抵の場合小規模な修正で直るけど、
どこを修正すべきか探すのに慣れとプロファイラが要る
>>596
GHC付属のプロファイラは優秀だと思う
600:36 ◆K0BqlCB3.k
08/08/23 15:47:59
>>596
profオプションをつけてコンパイルしたらランタイムシステムにプロファイラが組み込まれるよ。
詳しくはマニュアルで。
601:デフォルトの名無しさん
08/08/23 16:19:23
>>598
ん?確定はしてなくても最大どれかけかかるかは確定してるでしょ。
グラフ簡約のヒープ消費は予測もつかんぞ。
602:デフォルトの名無しさん
08/08/23 16:27:11
>>601
確定してるのかしてないのかどっちだw
603:初心者修業中
08/08/23 16:37:52
Haskellでメモリーリークが起きるのですか?
ガベージコレクションにバグがない限り、
メモリーリークが起きるとは思えないのですが…。
FFIを使った場合の事でしょうか…。
604:デフォルトの名無しさん
08/08/23 17:15:44
>>599 の例としては↓の話かな。
URLリンク(d.hatena.ne.jp)
この場合のメモリーリークは単なるメモリの解放忘れって事ではなくて、
期待した解放タイミングと実際のそれとのギャップの事みたいだね。
605:初心者修業中
08/08/23 17:42:49
これも「メモリーリーク」と呼ぶのでしょうか?
*Main> foldr (+) 0 [0..1000000]
*** Exception: stack overflow
606:デフォルトの名無しさん
08/08/23 18:05:58
プログラマが意図してないで、リファレンスが残るようなコーディングを
しちゃってる、というのをリークに含めることもある。
607:デフォルトの名無しさん
08/08/23 18:34:57
>>605
それは「マヌケ」と呼びます。
608:初心者修業中
08/08/23 18:57:56
stack overflowが発生する時、
簡単にわかる場合は「マヌケ」
ちょっとわかりづらい場合は「メモリーリーク」
と呼ぶという認識でよろしいでしょうか?
609:デフォルトの名無しさん
08/08/23 19:14:20
リークってのは「漏れ」のこと。
GCのある言語だと、>>606しか起こり得ない。
>>605の「溢れ」とは全然違う。
610:デフォルトの名無しさん
08/08/23 19:20:46
>>605
それはスタックオーバフロの例外であって、エラーとは違う。
メモリリークしているわけではないよ。
611:デフォルトの名無しさん
08/08/23 19:22:12
C言語みたいに型があいまいな言語ではメモリリークが起こりうるが、
Haskellみたいに強い静的型付けされている言語にはメモリリークなんてありえないよー
612:デフォルトの名無しさん
08/08/23 19:26:56
スタックオーバーフローとメモリーリークは
現象として全然違うと言う事ですね。
分かります。
613:デフォルトの名無しさん
08/08/23 19:53:14
>599や>604が挙げているような例はC言語で
良く言われる「メモリーリーク」とは違う現象だな。
Haskellの場合、遅延評価がデフォーなので
うかつに再帰を使うと計算の途中結果が膨大な
ものになってヒープ領域が溢れてしまう。
Cの場合はただの確保したメモリの解放し忘れ。
Cでも再帰的なメモリー確保をすれば
Haskellみたいな事も起きうるはずだが。
614:デフォルトの名無しさん
08/08/23 20:06:48
>>611
強い静的型付けとメモリーリークの有無はほとんど関係がありません。
GCの方がずっと関係が深いです。
615:デフォルトの名無しさん
08/08/23 20:09:24
Pascalのnewとfreeだっけ?
あれ考えれば分かるよな。
強い型付けでも簡単にメモリーリークは起きる。
616:デフォルトの名無しさん
08/08/23 20:56:45
foldl でも stack overflow するんだよね。
Data.List.foldl' 使えばいいんだけど。
617:デフォルトの名無しさん
08/08/23 21:35:43
なんで foldl でスタック溢れるの?末尾再帰が最適化されてないの?
618:デフォルトの名無しさん
08/08/23 21:48:31
>>604のリンク先に書いてある
末尾再帰は最適化されるよ
619:初心者修業中
08/08/23 23:53:01
>>617
遅延評価だからと認識しています。
↓参考
URLリンク(haskell.g.hatena.ne.jp)
620:617
08/08/24 00:40:37
>>618-619
なるほど、非常によくわかりました。
(つーか前出のリンク読まずにレスして申し訳ない)
うーむ、しかし末尾再帰が最適化されることの旨みは、
・ローカルスコープの値をスタックに積む必要がなくなることと
・連続するreturnが省略されること
の2点だと思うけど、foldl のように結局は遅延評価のための
computation がスタックに積まれていて、後から順次簡約するなら
「最適化されている」とは言い難い気もするな・・・。
最適化するための然るべき変形は、一応してあるんだろうけど。
まあ seq 使うとか、回避の仕方がないわけじゃないからいいのかな?
621:デフォルトの名無しさん
08/08/24 00:54:46
↓にも関連した話が載ってる。
URLリンク(itpro.nikkeibp.co.jp)
622:デフォルトの名無しさん
08/08/24 13:10:00
■■学校を作ろう!■■
VIP発でサイトを作ろうと思うんだ。(詳しくはWikiを見てくれ)
パートスレになるんでパー速(GEP)に移動している。
今スタッフを募集しているから、来てくれないか?
■Wiki
URLリンク(www36.atwiki.jp)
■募集スタッフ
プログラム担当(特にErlang、Perl)
デザイナー(サイト上のアイコン、ロゴなど)
WEBデザイナー(サイトデザイン案に沿って、htmlやCSSを書ける)
他にも宣伝担当なども募集している。
■スレ
URLリンク(ex14.vip2ch.com)
623:デフォルトの名無しさん
08/08/24 16:41:26
「特にErlang」…
実用性でいうとやっぱErlangなのかな…
624:デフォルトの名無しさん
08/08/24 18:20:21
>623
大規模なWebサービスを構築するのに向いていると
考えたから企画者がErlangを採用したんだろうね。
625:デフォルトの名無しさん
08/08/25 09:10:25
大規模な、ってのがクセ者で、
実情は単にDBのテーブルが大きいだけだったりするよな。
そもそもウェブアプリでDB以外どこが肥大化するよ?
626:デフォルトの名無しさん
08/08/25 09:11:28
画面?
627:デフォルトの名無しさん
08/08/25 09:20:29
>>625
複数のwebサービスから情報集めたり、もしくはhttp以外のプロトコルで通信して情報を取得しなきゃいけなかったり、
別プロセスで並列キューに入れて処理しなきゃいけなかったり、システムそのものが大きくなるとこはあると思う。
それともデータサイズの規模に限定した話?
628:デフォルトの名無しさん
08/08/25 09:53:32
>>625
とりあえずErlang + YAWSの事例くらいは、
念頭においてくれないと、話にならないのでは?
629:デフォルトの名無しさん
08/08/25 09:55:11
>>627
> 複数のwebサービスから情報集めたり、
そういうのはAjaxでクライアント側がやるのが流行では?
まあサーバ側がやってもいいですが、HTTPセッションを入れ子にするのは
あまり筋がいい設計とは思えません。
> もしくはhttp以外のプロトコルで通信して情報を取得しなきゃいけなかったり、
まあDB接続なんかもそうですよね。
しかし「大規模になる」ような要因とはあまり考えられないのですが。
> 別プロセスで並列キューに入れて処理しなきゃいけなかったり、
fastcgiとかの話でしょうか?特段、だから大規模になるというものではないと思いますが。
> それともデータサイズの規模に限定した話?
コード自体はほとんどCMS系フレームワークをユーザ定義コンテナを定義する程度で
用が済むことが多いと思います。特に、>>622のような、いかにもCMSっぽいシステムでは。
630:デフォルトの名無しさん
08/08/25 10:00:08
>>629
> コード自体はほとんどCMS系フレームワークをユーザ定義コンテナを定義する程度で
> 用が済むことが多いと思います。特に、>>622のような、いかにもCMSっぽいシステムでは。
よいCMS系フレームワークを、
容易に開発できるかどうかって話をしているんだと思いますよ。
631:デフォルトの名無しさん
08/08/25 10:54:21
>>630
なるほど、わかりました。
格納するコンテンツの量は結局DBのサイズの問題になると思うので、
それ以外の「大規模」の要因というと、
・同時接続数(パフォーマンス)
・登録ユーザー数
ぐらいでしょうか。
それとも単純にコードサイズを指して「大規模」という話なんでしょうかね。
「学校」というドメインが明確になっているので、
一般のCMSフレームワークほど汎用化は要求されないし、
どのような要因でコードサイズが「大規模」化するのか興味があります。
632:デフォルトの名無しさん
08/08/25 12:22:00
>>624
Apacheとか使わずErlangでサーバー構築するんじゃないの?
633:デフォルトの名無しさん
08/08/25 12:26:39
キッチンシンクアプローチか……
634:デフォルトの名無しさん
08/08/25 13:01:50
Erlangをわざわざ使うということは、数百レベルの並列プロセスを
マルチコアで何とかしようと考えていると見て間違いない。
Webだとすれば、WebServer以外考え難い。生徒数千でほぼ
同時にアクセスがあるとか。
635:デフォルトの名無しさん
08/08/25 13:13:15
しかし、>>622 はなんでErlangスレに書いてないんだ?w
636:デフォルトの名無しさん
08/08/25 13:16:41
単に初期メンバーにErlang使いが居ただけなじゃいの?
637:デフォルトの名無しさん
08/08/25 13:16:52
Erlangスレ見たことない方ですねw
638:デフォルトの名無しさん
08/08/25 13:42:02
Erlangはどうでもいいんだけれど、
HaskellでもPerl使いを確保しておいて、単体の機能は専らCPANから取り出させて、
確保されているインターフェイスを介してHaskellで利用するというやり方は
多くなるんじゃないかな。短時間で開発する一手法としてね。
639:デフォルトの名無しさん
08/08/25 13:57:49
ならないね。
640:デフォルトの名無しさん
08/08/25 14:13:29
>>638 落日のPerlを使うかどうか。 規格書の通りに一からすべて開発するのは確かに大変だね。
641:デフォルトの名無しさん
08/08/26 00:21:14
Text/ParserCombinators/ReadP.hsとKoen Claessen氏のペーパーを読んで思ったんですが、
Haskellに慣れてくるとこの実装が直感的に見えてくるんですか?
Haskellのパーサコンビネータ関連のペーパーを読んでいない状態でReadPを読んで、
data P a = Get (Char -> P a)
略
| Result a (P a)
略 なのを「え、一番直感的じゃん」
とか、
newtype ReadP a = R (forall b . (a -> P b) -> P b)
で
instance Monad ReadP where
return x = R (\k -> k x) ← これとか
fail _ = R (\_ -> Fail)
R m >>= f = R (\k -> m (\a -> let R m' = f a in m' k)) ← これとか
とか
get = R Get
ってなるを、「ああ、自明だなすげえ直感的」みたいに理解できるようになる物なんですかね。。難しすぎる。。。
642:デフォルトの名無しさん
08/08/26 00:29:58
>>629
大規模になる要因なんていくらでもあるじゃん。
今時は単にUIがWebで、バックエンドが複雑化してるものも少なくないしね。
分散業務システムで多種類のプロセスを相手にすりゃ自然と規模は大きくなるかと。
何でもかんでもインターネット上でパブリックに利用可能な整理されたサービスばかりじゃないからね。
学校だって企業並みにシステムが複雑化してるとこもあるから、強ち単純とは言えないんじゃないかと。
まあ何はともあれ、ロジックが複雑になればなるほど、関数型の恩恵は大きくなるわな。
643:デフォルトの名無しさん
08/08/26 01:08:51
といったって、googleも複雑なシステムとか言われてるけど、
googleを支える技術とか読んでもそんなに複雑とは思えないんだよなぁ。
台数は1台だけど自宅で似たようなことやってるもん。
644:デフォルトの名無しさん
08/08/26 08:11:38
>>641
P のような再帰的な型のモナドを、
効率のために継続モナド(ReadP)で包むのは定石。
Haskell への慣れっていうより、
モナドや継続モナドへの慣れの問題な気がする。
P は問題によって様々だけど、
ReadP のとこは Control.Monad.Cont の
一般的な継続モナドと(型を除いて)同じなので、
それを理解しておくと問題に集中できていいかもよ。
645:デフォルトの名無しさん
08/08/26 08:13:32
つ チラシの裏
646:デフォルトの名無しさん
08/08/26 08:21:08
>>642
それはバックエンドで動いている他プロセスが複雑なのであって
ウェブアプリが複雑なわけではないのでは?
647:デフォルトの名無しさん
08/08/26 08:32:48
>>625
機械翻訳とかではなくて?
648:デフォルトの名無しさん
08/08/26 18:38:57
>>644
どうもレスありがとうございました。
>P のような再帰的な型のモナドを、
>効率のために継続モナド(ReadP)で包むのは定石。
これは初めて聞きました。どうもありがとうございます。
確かに
If we want to build monads on top of a continuation based programming paradigm,
such as stream processors or continuation based I/O in Haskell,
we need to build a monad around the continuation based operations.
って書いてあるペーパーを見付けました、その継続ベースの方法について考えながら考えていこうと思います。
649:デフォルトの名無しさん
08/08/26 18:52:43
URLリンク(www.cs.chalmers.se) でしょ
650:デフォルトの名無しさん
08/08/26 19:00:04
>>649
そうです、でもこれだけ読んでもこれで何がしたいのか俺には正直よく分かりませんな。。
例がなくても理論だけ聞けば全て分かるタイプの人なら大丈夫なのかもしれませんが。
651:デフォルトの名無しさん
08/08/28 06:47:20
>>648
P みたいなのを継続ベースともいうけど、
ReadP を使うのは純粋に効率のためで、
そこに書いてあるのとは話が違うような。
652:デフォルトの名無しさん
08/08/28 11:12:38
> 純粋に効率のためで
そう単純化されても…
653:デフォルトの名無しさん
08/08/28 14:48:42
いや、単純だし…
654:デフォルトの名無しさん
08/08/28 21:41:23
具体的にどういう場合にどうして効率が良くなるんですか?
ReadPだと、PがReadPで包まれてるわけだけど、
get' = Get return
look' = Look return
sat' p = do a <- get' ; if p a then return a else Fail
char' c = sat' (c == )
string' s = do str <- look' ; scan s str
where scan [] _ = return s
scan (x:xs) (y:ys) | x == y = do get' ; scan xs ys
scan _ _ = Fail
みたいにReadPでくるまないバージョンも用意できて、それもrunで使える。
URLリンク(www.cs.chalmers.se)
ここにも効率がって書いてあるけどどんな場合なのかさっぱりだ。。
655:デフォルトの名無しさん
08/08/29 14:13:46
ReadPはdata宣言じゃなくてnewtype宣言だから、
記述上は包まれた形になってるけど、実装では包みが外れた形になる。
参照: URLリンク(haskell.g.hatena.ne.jp)
Pは直接的にはうまく束ねることができないから、一旦仮想的なReadPで束ねてるって感じ?
656:デフォルトの名無しさん
08/08/29 15:53:54
>>655
どうもありがとうございます。
実際にはReadPの所はR Get やR Lookなどが渡されることになりますよね。
そのあとすぐにrunで即Rはずしてますし。
>Pは直接的にはうまく束ねることができないから
これってどういう意味で仰ったんですか?
P を束ねてパーサとして使うことも、実際できる(>>654のget'など)のでわざわざどうしてReadPにするのか、
Pの>>=が左結合的に作用するのが問題らしいんですけどそれが問題になる具体的なケースについて
私にはサッパリ思い付かなかったので先人たる皆様にお聞きしたかった次第です。
657:デフォルトの名無しさん
08/08/29 17:28:28
>>654
ReadP の計算で左結合になってる >>= がある場合でも、
内側の P の >>= をすべて右結合にすることで、
P の >>= の再帰が無くなって効率が良くなる。
9節の第1パラグラフに書いてある通りなんだけど。
左結合を右結合にってのは、>>= の結合則
(m >>= f) >>= g == m >>= (\a -> f a >>= g)
の左辺を右辺にするってな話。
例えば、string s >>= f でも string s の中で
>>= を使ってるので、左結合になってる。
つまりほとんど全ての場合に当てはまる。
658:デフォルトの名無しさん
08/08/29 17:29:19
効率が悪くなる事情は、そこにも書いてあるようにリストの ++ と同じ。
リストの ++ は左引数に関して再帰する。
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
そのため (xs ++ ys) ++ zs は xs に関して二重に再帰することになる。
foldr (++) [] (map show [1..10000])
foldl (++) [] (map show [1..10000])
実際これらを実行してみると前者はすぐ終わるけど、後者は "1" を10000回結合、
"2" を9999回結合、... "10000" を1回結合、みたいになって遅い。加速してくけど。
遅いだけじゃなく、中間リストを生成するので無駄にメモリを使うことにもなる。
foldl は極端な例だけど、foldr も極端で、いつも無駄が無いようにはいかない。
659:デフォルトの名無しさん
08/08/29 17:30:18
で、回避策。
xs ++ ys は、xs の最後の [] を ys に置き換える。
それを効率よくやるには、最初っから [] なんか使わないで、
1:2:3:[] を \nil -> 1:2:3:nil みたいにしとけばいいじゃんという発想。
つまり [a] を [a] -> [a] に、xs を xs ++ に、++ を (.) にする。
こうしておくと、[] を与えてリストに戻すときには、
(.) が右結合になってなくても ++ は右結合になる。
(((xs ++) . (ys ++)) . (zs ++)) []
= ((xs ++) . (ys ++)) (zs ++ [])
= (xs ++) (ys ++ (zs ++ []))
= xs ++ (ys ++ (zs ++ []))
実際 String の ++ を頻繁に使う class Show あたりでは、
できるだけ type ShowS = String -> String を使うことになってる。
shows :: Show a => a -> ShowS を使ってさっきの
foldl (.) id (map shows [1..10000]) []
をやってみると、今度は問題無く速い。
660:デフォルトの名無しさん
08/08/29 17:31:29
で、ReadP。
m >>= f (P の >>=)は、m の最後の return a を f a に置き換える。
それを効率よくやるには、最初っから return なんか使わないで、
Get (\c1 -> Get (\c2 -> return [c1,c2])) を
\k -> Get (\c1 -> Get (\c2 -> k [c1,c2])) みたいにしとけばいいじゃんという発想。
つまり P a を forall b. (a -> P b) -> P b に、
m を m >>= に、>>= を \m f k -> m (\a -> f a k) にする。
以下略。
661:デフォルトの名無しさん
08/08/29 17:32:22
で、余談。
foldr c n xs は、xs の : を c に、[] を n に置き換える。
それを効率よくやるには、最初っから : や [] なんか使わないで、
1:2:3:[] を \c n -> 1 `c` 2 `c` 3 `c` n みたいにしとけばいいじゃんという発想。
つまり [a] を forall b. (a -> b -> b) -> b -> b にする。
リストに戻すときは build xs = xs (:) [] を使う。
すると foldr c n (build xs) ==> xs c n と変換できる。
map f xs <==> build (\c n -> foldr (c . f) n xs)
例えばこういう変換を定義すれば、
(map f . map g) xs = map f (map g xs)
==> build (\c n -> foldr (c . f) n (build (\c n -> foldr (c . g) n xs)))
==> build (\c n -> (\c n -> foldr (c . g) n xs) (c . f) n)
==> build (\c n -> foldr (c . f . g) n xs)
==> map (f . g) xs
のように map f . map g ==> map (f . g) という変換ができる。
map f . map g 以外にも、他のいろいろなリスト関数の
foldr/build を使った形への変換を定義しておけば、いろいろな変換ができる。
foldr/build による融合変換ってやつ。今の GHC もこれを使ってる。
詳しくは GHC User's Guide の 8.13. Rewrite rules あたりを見てくれ。
662:デフォルトの名無しさん
08/08/29 18:19:15
>>657-661
とても分かりやすい解説どうもありがとうございます!
ちょっと解決の糸口がつかめた感じがします、これからじっくり考えてみたいと思います。
とてもご丁寧にありがとうございました。
流石だ。。。
663:デフォルトの名無しさん
08/08/30 18:34:32
Haskellが宣言型言語とか最初に言い出したのは誰なのかしら
664:デフォルトの名無しさん
08/08/30 18:44:45
imperative language ←→ declarative language の対比で
ごく自然発生的なものだと思うが?
665:デフォルトの名無しさん
08/08/31 00:07:29
宣言型言語 = what(何をしたいか)を記述
手続き型言語 = how(どうやるか)を記述
クロージャをいかに早めに潰すかに苦心するHaskellは後者ですな
666:デフォルトの名無しさん
08/08/31 00:38:36
>>665
宣言型言語=述語論理を記述
と思ったらHaskellも述語論理の仕様記述言語に非常に近い特徴を持っていることに気づく。
667:デフォルトの名無しさん
08/08/31 03:38:00
>>665
> クロージャをいかに早めに潰すかに苦心
ってどういうこと?
668:デフォルトの名無しさん
08/08/31 09:45:13
>>667
関数のインライン展開のようなものじゃないか
よく分からんが
関数リテラルなら展開しやすいが高階関数の戻り値のクロージャは展開しにくい気がする
だからどう書くか (how) を工夫する
人間が問題を「宣言」するだけでコンパイラが問題を解いてくれる
というのは
素朴な解決策は簡単に見つかるのだが最適化が難しい (が機械的にできる) 問題に限定されるはず
669:デフォルトの名無しさん
08/08/31 15:47:12
計算資源が有限なため、howが分からないとwhatも記述できないという罠
670:デフォルトの名無しさん
08/08/31 15:59:09
本質的には what -> how の書き換えと how -> how の最適化は似たようなもんだからな。
最適化は手続き型でもやってるから、非手続き型の人はwhatの部分を強調してみたりC/C++より速くなると言ってみたり。
LLの人は最適化にあまり拘らないし、テストさえ通ればhowを直接書いてもいいやって感じだけど。
671:デフォルトの名無しさん
08/08/31 17:18:22
>>667
>>600前後の流れ参照
要するに未評価の式(これはクロージャで実装されてる)を溜め込まないように注意する必要がある
672:デフォルトの名無しさん
08/08/31 20:51:42
しかし、そんなこと言ってたらprologだって宣言型と言えなくなるんじゃない?
673:デフォルトの名無しさん
08/08/31 21:42:38
お前らは
人間の性格はA型B型O型AB型の4種類に分けることができる
とか思ってそうだよな。
674:デフォルトの名無しさん
08/08/31 23:36:24
なんでも過不足なく分類できると思い込む愚かさ
血液型と性格をろくな検証なしに簡単に結びつけてしまう短絡さ
どっちをさしてるのか紛らわしいので例としては不適
675:デフォルトの名無しさん
08/09/01 01:06:10
>>674
おもしろおかしい
676:デフォルトの名無しさん
08/09/01 07:57:32
URLリンク(www.realworldhaskell.org)
書き終わったって。
677:デフォルトの名無しさん
08/09/01 15:40:49
zipで(ry
678:デフォルトの名無しさん
08/09/02 14:15:50
>>666 プ
試しにZあたりの実行系でもつくってみればw
679:デフォルトの名無しさん
08/09/02 17:56:25
>>678
何が言いたいのははっきり言え。
小馬鹿にするだけでは情報価値ゼロだぞ。
680:デフォルトの名無しさん
08/09/03 08:50:51
述語論理なめんな、ってことじゃね?
せめてホーン論理に限定するとかじゃないと話にならんだろ。
681:デフォルトの名無しさん
08/09/03 23:53:10
関数とKleisli以外のメジャーなArrowってあるの?っていうかArrowって死滅したの?
682:デフォルトの名無しさん
08/09/04 00:04:13
>>676
おお!でも英語疲れる。訳書出版の予定はないの?
683:デフォルトの名無しさん
08/09/04 01:25:52
>>681
死滅しそうなのはHaskellだが、新しいHaskellのライブラリはほとんどArrowベースだよ。
684:デフォルトの名無しさん
08/09/04 11:41:24
このスレって嘘多いよな。
685:デフォルトの名無しさん
08/09/04 12:00:02
このスレって〜
ってレス多いよな。
686:デフォルトの名無しさん
08/09/04 15:00:58
そういえば、大学入試のときに大学ランクとタバコの関係に気づかされたなぁ・・・
東大 誰も吸っていない
京大 誰も吸っていない
同志社大 ちらほら
関西大 校舎内で吸っているやつがいる(!!!)
ありえないです、低ランク大・・・
やっぱりランクの低い大学出身のやつは信用できない・・・
687:デフォルトの名無しさん
08/09/04 15:19:00
そして増える意味不明なレス
688:デフォルトの名無しさん
08/09/04 15:20:04
>>684
素人なのでどの変がうそなのか教えてください
689:デフォルトの名無しさん
08/09/04 15:45:52
686みたいな奴がhaskellを使うとはとても思えんのだが、
何しに来てるのかね?
690:デフォルトの名無しさん
08/09/04 15:50:35
>>689
Haskellがどういうものだと思っているんですか?
691:デフォルトの名無しさん
08/09/04 17:36:25
>>686は今マルチされてるコピペ、スルー推奨です。
692:デフォルトの名無しさん
08/09/04 19:33:03
>>690
全角数字を見るといらっとくる人が使う言語
693:デフォルトの名無しさん
08/09/04 19:35:16
確かにイラっときた
694:デフォルトの名無しさん
08/09/04 21:21:38
>>693
それはカルシウム不足
695:デフォルトの名無しさん
08/09/06 23:15:53
Haskellで良いコード綺麗なコードというのはどんなコードですかね。
出来るだけ変数使わない方がいいとか、何が何でもポイントフリーにするとか、
あるいはそれ以外でも、何でも。
696:デフォルトの名無しさん
08/09/06 23:55:28
>>695
y f = f (y f)
697:デフォルトの名無しさん
08/09/07 00:05:33
>>695
haskellでは数学的にきれいなコードが「きれいなコード」と呼ばれます。
698:デフォルトの名無しさん
08/09/07 00:12:32
良いコード:
意味のあるところでControl.*を使う
悪いコード:
ポイントフリーのためにControl.ApplicativeやControl.Arrowをimport
699:デフォルトの名無しさん
08/09/07 00:15:18
っていうか、ポイントフリーってなにがいいの?せっかくパターンマッチがあるのに。
>>687
ライブラリはそうだろうけど、普通のアプリを書くときは?
700:デフォルトの名無しさん
08/09/07 00:33:20
単純な場合には無駄に変数が増えず、シンプルに分かりやすくなるから良い。
複雑な場合には無理をしても分かりにくくなるだけだから悪い。
パターンマッチとは使いどころが違う。
701:デフォルトの名無しさん
08/09/07 00:34:19
>>699
圧倒的に短く書けるからだよ。
それにポイントフリーだと関数の入出力の流れみたいなのがまっすぐ表せるから、処理の全貌が見通しやすい
702:デフォルトの名無しさん
08/09/07 00:41:52
まっすぐだけど、流れが逆じゃん。
というわけで>>>使うのはやっぱダメ?逆なのに脳味噌合わせるべきなの?
703:デフォルトの名無しさん
08/09/07 00:46:48
GUIアプリを書くときはどういうのが綺麗なんだ?
704:デフォルトの名無しさん
08/09/07 00:59:26
>>702
逆なの? y = f x より x f = y が脳味噌に合ってるの?
705:デフォルトの名無しさん
08/09/07 01:11:04
>>704
なんでやねん。
unlines . take 10 . filter (> 10) . map read . lines
より、
lines >>> map read >>> filter (> 10) >>> take 10 >>> unlines
の方が、少なくとも俺は脳に優しく感じる。
で、こう書くと、map read と filter (> 10) を分けてるのが冗長でダサい気もするが、
(filter (> 10).read)みたいにした方が良いのか、かえってこっちの方がダサいのか、
あるいは、(filter (\x -> 10 > read x)) みたいにラムダにすべきなのか、綺麗の勘所が判らんのです。
706:デフォルトの名無しさん
08/09/07 01:12:53
>>705
あ、前半がStringに戻してないのはご愛敬と言う事で、よろしく。
707:デフォルトの名無しさん
08/09/07 01:32:55
>>705
String に戻さないといけないなら
filter ((10 <) . read) だろう。ラムダでもいいけど。
まあ、その辺はこだわるとこでもないかと。
> なんでやねん。
f (g x) と (f . g) x の向きは関係あるんですよ。
数学でも向き的事情から x^f という記法を使うこともある。
708:デフォルトの名無しさん
08/09/07 02:23:43
>>702
左から右だろうが右から左だろうがどっちでも一緒だろ。
俺には違いが分からん。
709:デフォルトの名無しさん
08/09/07 02:27:05
>>702
こういう反抗したい年頃のやつが言語を汚くしていくんだろうな。
なんでもないものを指差して「使いにくい」などと言ったり、まるでガキ。
710:デフォルトの名無しさん
08/09/07 03:31:39
現代日本では横書き文字は左から右だから、
その方が自然に感じるのは当然と思います。
また、bind演算子が(>>=)で左結合である事を考えても
Haskellを設計した人もその方が自然と感じたのではないでしょうか?
慣れの問題かもしれませんが、
そんなにおかしな意見とは思えません。
711:デフォルトの名無しさん
08/09/07 07:34:52
まあ関数合成の向きが右から左なのは>>707の説明の通りだし、Haskellに限らず数学でも同じルールだからな。数学でも気持ち悪いって云う人は結構居るしまあそんなに変わった意見でもあるまい。
712:デフォルトの名無しさん
08/09/07 21:48:37
社内コーディング規約でここにスペースを入れろとかそういうのよりは高尚が感じがするかもしれないけれど
所詮バイクシェッド
乱用すれば読みにくいし、パズルみたいにポイントフリーするのは間違ってる
数学的に綺麗綺麗とか、圏論的に自然とかというけれど、誰でも圏論がわかるわけじゃないし。
しかし、いかにポイントフリーで書くか、という事を考えると確かにおもろいよ
713:デフォルトの名無しさん
08/09/07 21:56:43
亀だが
>>36
>FPGAとかのHDL記述とかに応用したりしてる人いないの?
Lavaがあるよ。並列性とか関係ないし、回路をそのまま関数で書くだけなんだけど。そしてVerilogより使いやすい、なんてこたーない。HDLよりましだが、副作用を書くのがまわりくどい
URLリンク(www.cs.chalmers.se)
714:デフォルトの名無しさん
08/09/07 22:31:52
s/HDL/VHDL/
715:デフォルトの名無しさん
08/09/08 21:55:12
>>713
ArrowっぽいHDL作りたいな
716:デフォルトの名無しさん
08/09/09 18:48:21
Real World Haskell
November 15, 2008
待ち遠しい。
717:デフォルトの名無しさん
08/09/12 22:50:22
過度の並列化で複雑化するゲーム開発
コスト削減の鍵は純粋関数型言語らしい
URLリンク(www.watch.impress.co.jp)
718:36 ◆K0BqlCB3.k
08/09/12 22:54:50
>>717
そうだろうね。
俺はずううっと前からそう論文に書いてたけど。
だんだんpi-calculusの人気が出てきたね。
719:デフォルトの名無しさん
08/09/12 23:58:55
> Sweeney氏は純粋関数型言語のもつ並列処理安全性に着目しており、
>将来的にゲームプログラミングはそういった処理系に移行していくべきだとした。
>Sweeney氏はそのひな形として言語“Haskel”を挙げているが、
>ゲーム開発のメインストリームたり得る言語はまだ登場しておらず、将来に期待しているという。
なんでHaskellは駄目なんだろう。
ライブラリ含めた開発環境の問題か処理系の最適化の問題か
それとも言語仕様レベルで本質的に向いていないのか。
720:デフォルトの名無しさん
08/09/13 00:06:19
前者じゃない?
721:デフォルトの名無しさん
08/09/13 00:09:07
こんなことでもないと注目せんのだな
722:デフォルトの名無しさん
08/09/13 00:48:51
遅延評価に漬かりまくりで、ダメなのでは?
遅延評価って言ってみれば、後ろからの逐次でそ?
無限リスト使えないHaskellってHaskell?
723:デフォルトの名無しさん
08/09/13 07:07:42
LazyがいやならSMLやOCAML使えばいいだけ。何が不足よ?
724:デフォルトの名無しさん
08/09/13 08:23:12
>>723
前方参照,where構文
725:デフォルトの名無しさん
08/09/13 09:32:44
>>724
LETで何が不足よ?
726:デフォルトの名無しさん
08/09/13 10:42:16
>>717,>>719からのコンテキストを読んでくれよ。
727:デフォルトの名無しさん
08/09/15 18:14:08
質問です
たとえばJavaなどではクラスのインスタンスをオブジェクトと呼びますが、
Haskellの代数的データ型に格納されたデータのことをなんと呼べば良いですか?
728:デフォルトの名無しさん
08/09/15 18:21:45
>>727
関数
729:デフォルトの名無しさん
08/09/15 19:00:09
>>727
「オブジェクト」に対応する用語は普通は「値」でいいんじゃないか
>Haskellの代数的データ型に格納されたデータ
これどういう意味?
型が代数的データ型であるような値のことならそのまま「代数的データ型の値」
代数的データ型の構築子に渡した値のことなら「フィールドの値」くらいか?
data Point = Pt Int Int
x = Pt 0 3
-- xはPoint型の値
-- xのフィールドの値は0と3
730:デフォルトの名無しさん
08/09/15 20:26:27
Haskellのプログラミングスタイルのことはなんて呼べばいいですか?
ストリーム指向?
731:デフォルトの名無しさん
08/09/15 20:30:20
関数指向
732:デフォルトの名無しさん
08/09/16 23:55:40
Haskell系のShellでオススメってある?
733:36 ◆K0BqlCB3.k
08/09/17 00:00:30
>>732
シェルって何のこと?
言語とは関係ないと思うけど。
シェルスクリプトのことを言っているの?
734:デフォルトの名無しさん
08/09/17 00:07:44
>>733
HSHみたいなやつ
探してみた奴だとどれも開発止まってて…
735:デフォルトの名無しさん
08/09/17 00:09:07
Haskell風構文のシェルっていくつかあるんだな、ググって初めて知ったわ
736:デフォルトの名無しさん
08/09/17 00:15:11
Haskell系の自然言語でオススメってある?
737:デフォルトの名無しさん
08/09/17 00:22:13
lojbanとか?
自然言語じゃないけど
738:デフォルトの名無しさん
08/09/17 15:52:29
Yiとか使ってる人いるの?
739:デフォルトの名無しさん
08/09/17 17:56:30
Yi って 彝 ?
740:デフォルトの名無しさん
08/09/17 18:20:56
ぅぃ?
741:デフォルトの名無しさん
08/09/17 18:31:27
URLリンク(haskell.org)
使ったこと無いなぁ。
742:デフォルトの名無しさん
08/09/19 17:29:49
ひょんなことからerlangを勉強し始めたが、構文はともかく、思想としては面白いな。
並行指向プログラミングというのかな?
このパラダイムはオブジェクト指向よりも現実志向のパラダイムのように思う。
Haskellでも並列化がうまくいけばerlangみたいな仕組みを実装できるかもしれない。
# erlangの構文は糞 糞 糞 糞杉
743:デフォルトの名無しさん
08/09/19 18:18:31
ぅぃゅ
744:デフォルトの名無しさん
08/09/19 20:28:25
コンカレントハスケル?
745:デフォルトの名無しさん
08/09/19 20:34:40
ああ、コンカレントは並行だったか・・・
746:デフォルトの名無しさん
08/09/20 11:00:42
>>743
私はProlog屋なので、erlangの構文のクソ部分に敏感でない。
お手数かけて恐縮だが、糞の部分を列挙していただけると有難いのだが。
747:a36 ◆K0BqlCB3.k
08/09/20 12:04:07
>>742
たぶん、その思想というのはpi-calculusのことかな。
748:デフォルトの名無しさん
08/09/20 13:08:03
ここのみんなからするとgtk2hsって綺麗なの?
749:デフォルトの名無しさん
08/09/20 13:29:19
Erlangってpi-calculusベースなのか
750:デフォルトの名無しさん
08/09/20 13:56:48
>>746
743ではないけど、
receive...endとか、カリー化できないとかではないですか?
751:デフォルトの名無しさん
08/09/20 14:52:33
>>723
元記事ではSTMが挙げられてるけど、OCamlだと無くね?
>>749
綺麗って何が?Gtk2Hsを使ったコード?
それならあまり綺麗じゃないんじゃない。
GUIを綺麗に書くためのハイレベルなライブラリは
いろいろあるけど、どれも決定打にはなってないような。
752:デフォルトの名無しさん
08/09/20 15:23:34
>>751 >>749 じゃなくて >>748 ?
753:デフォルトの名無しさん
08/09/20 15:27:39
>>752
>>748な俺からでもそれはわかる。
754:デフォルトの名無しさん
08/09/21 00:46:57
gtk2hsと言えば、
gtk_rc_parse_string相当の関数や、
gtk_widget_modify_cursor(これは新しいからか)相当の関数が見付からなくて諦めたことがあります。。
いや私の検索能力が低いだけだと思うんですが、かなり頑張ってもどうしても見つかりませんでした。。。
皆さんgtkやpango、gdkの関数を捜すときってやっぱり根性ですか?
大抵はキャメルケースにすれば大丈夫ですがそうでない時はかなり困りますよねー。。
755:デフォルトの名無しさん
08/09/21 12:17:25
いや、検索能力の問題じゃなくて、実際に無いんじゃない?
Gtk2Hsのソースgrepしてみて無かったら無いような。
756:デフォルトの名無しさん
08/09/22 08:20:06
webで読んでるけどreal world haskell凄いヴォリュームだな
一週間やってもまだ終わらん
製本版はもう鈍器レベルだな
757:デフォルトの名無しさん
08/09/22 09:55:41
なにか面白いこと書いてあった?
758:a36 ◆K0BqlCB3.k
08/09/22 15:02:13
これでしょ
URLリンク(book.realworldhaskell.org)
759:デフォルトの名無しさん
08/09/22 16:29:27
url知らないって意味じゃなくて、自分では読む気が無いってことだよ。
760:a36 ◆K0BqlCB3.k
08/09/22 16:37:06
ぱっと見た感じでは、名前の通り実際にHaskellで開発する時に「背中に手が届く」本になってる感じ。
たとえばデータベースと通信する方法とか、
GUIを作るときのライブラリとかツールとかの紹介とか、
どちらかというと「Haskell逆引きクイックリファレンス」
みたいな感じだね。
目新しいことは何もないけど、逆引きリファレンスとしてはいろんなライブラリとか紹介されていて便利かな。
761:a36 ◆K0BqlCB3.k
08/09/22 16:39:11
いろいろサンプルコードも載ってるからわかりやすい。
文章の良よりコードの両方の方が多いから英語が苦手な人でもわかると思う。
762:a36 ◆K0BqlCB3.k
08/09/22 16:39:49
良 → 量
コードの両方 → コードの量
763:デフォルトの名無しさん
08/09/24 11:57:39
Parsec.Tokenをロードすると
ERROR file:{Hugs}\packages\parsec\Text\ParserCombinators\Parsec\Token.hs:64 - Syntax error in data type declaration (unexpected `.')
とでて読み込めないのですがどうしたらいいのでしょうか
764:デフォルトの名無しさん
08/09/24 12:09:05
>>763
Hugsを標準モードじゃなくて拡張モードで起動すればいい
hugs -98
765:デフォルトの名無しさん
08/09/24 12:51:18
>>764
無事読み込めました。ありがとうございます
766:デフォルトの名無しさん
08/09/24 15:23:46
do構文で、変数の使用が強制されるのはなんとかならんの?
.とか$とかの気の利いたバージョンない?
767:デフォルトの名無しさん
08/09/24 15:27:56
何を言ってるのかよく分からんが >>= とか?
768:デフォルトの名無しさん
08/09/24 15:36:59
>>=だけですっきりいけるならdo構文使わないでしょ(ってこともないか?少なくとも俺は)。
do構文でモナドを「外す」ためだけに一時変数がやたら必要になるのがイヤって話。
つまるところ>>=になっちまいそうな気もするけど、
便利な演算子なり特殊なカッコなりで、無駄な変数使わずに何とかならんかなぁ、と。
769:デフォルトの名無しさん
08/09/24 16:11:24
なにか具体例見せてくれ
770:デフォルトの名無しさん
08/09/24 16:18:02
do式の中で、
a <- v
b <- f a
は、aを使わずに
b <- v >>= f
と書ける
同様に、
a <- v
let b = f a
は、
b <- liftM f v
と書ける
こういう話?
>>=は普通にdo構文の内部で使えるよ
俺はこの場合=<<を使う方が好きだけど
771:デフォルトの名無しさん
08/09/24 16:26:30
何を言ってるのか俺もよく分からん。
do ...; a <- m; f a; ...
を
do ...; f =<< m; ... -- m >>= f でも同じだけど...
とか
do ...; a <- m; let b = f a; ...; g b; ...; h b; ...
を
do ...; b <- liftM f m; ...; g b; ...; h b; ...
とかすればいいって話じゃなくて?
って書き込もうとしたんだけどその前に新着レス見たら>>770被りすぎ。
772:デフォルトの名無しさん
08/09/24 16:44:57
n <- m
a <- n
を
a <- join m
にするパターンもあるかも。
n <- m
o <- n
a <- o
を
a <- join (join m)
とか。
773:デフォルトの名無しさん
08/09/24 16:48:50
ぱっといい例は書けないけど、例えば単純な例で
do args <- getArgs
cnt <- getContents
now <- getClockTime
return someFunc args cnt now
を、
do return soumeFunc #getArgs #getContents #getClockTime
とかこんな感じに書けないかと。(#が架空のモナド外し演算子とか)
774:デフォルトの名無しさん
08/09/24 16:53:15
>>770,771,772
ありがとう。特にjoinは使った事なかった。
俺がアホでした。
775:デフォルトの名無しさん
08/09/24 16:56:54
あれ?やっぱ違うや。求めてるのとjoin。いや、それはそれで勉強になったけど。
776:デフォルトの名無しさん
08/09/24 17:01:37
というか、liftM3ですね。とりあえず釣って来ます。
777:デフォルトの名無しさん
08/09/24 17:21:21
ちなみに、
do args <- getArgs
cnt <- getContents
return otherFunc args True cnt
だったら?
778:デフォルトの名無しさん
08/09/24 17:27:31
>>773みたいな構文は俺も欲しい
このスレで前に同じことを書いた記憶がある
Template Haskellを使えばなんとかなるかな
>>777
liftM3 otherFunc getArgs (return True) getContents
不恰好だけど
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5212日前に更新/225 KB
担当:undef