関数型プログラミング言語Haskell Part5
1 :
デフォルトの名無しさん :
2006/06/03(土) 00:53:50
クソ言語
┏┳┳┓ ハイ. ┏┳┳┓ ┏┫┃┃┃ うんこは. ┃┃┃┣┓ ┃┃┃┃┣┓ ここまで ┏┫┃┃┃┃ ┃ ┃┃┏━━━┓┃┃ ┃ ┃ うんこ. ┣┫ . ・∀・ ┣┫. STOP!┃ ┗━━━━┛┗┳━┳┛┗━━━━┛ ┏┻┓┃ ┏━┛ ┣┻┓ ┗━━━┫ ┗━┓ . ┗━━━┛
7 :
デフォルトの名無しさん :2006/06/03(土) 07:28:45
うむ
>>前スレ997-998 日本でHaskellがはやってることを世界に知らしめてどうしようっていうんだ。 HWNだって意図からして情報量を抑えて内容を精選するべきなんだから、 役に立たず、興味も引かない情報を載せる余裕はないだろ。
( ゚д゚)ポカーン
11 :
10 :2006/06/03(土) 15:25:08
>>10 なんか分かった気がする。
getChar :: IO Char のように、
評価する毎に次の文字が取得できるモナドを
仮定しているような気がしてきた。
>>11 それで合ってる。
細かいことをいうと、getCharはモナドではなくて動作(アクション)で、
動作に対して行うのは評価ではなくて実行ね。
13 :
10 :2006/06/03(土) 17:09:08
MLでええやん
MLって寂れてるよね 未来がなさそう
だから他の言語の話をするなと
17 :
デフォルトの名無しさん :2006/06/03(土) 20:15:33
あってて良かった遅延評価のケースを語ってくれ
俺はまだhaskell歴1ヶ月のしろーとで、まだまだ分かってないことも多いので、 もっと他にもいろいろあると思うが、俺の体験から言うと、 1.再帰関数による探索をしているアルゴリズムで、枝刈りが簡単にできる。 2.遅延(無限)リスト。 3.再帰関数でリストを作りながら、それを別の関数に突っ込める。 といったところかな。 こういったことができるとことで、より宣言的にプログラムが書けるような気がする。 まあ、「あってて良かった正格評価(指定)」のケースも結構あるけどね。
19 :
18 :2006/06/04(日) 02:35:53
「あって良かった」だな……
そして、先行評価と遅延評価を細かくチューニングできるような仕組みを求める声が上がり、 だが次第にそのチューニングすらめんどくさくなってきて「解析して自動的にうまいこと 切り替えるようにしてくれよ」とか言われだすが、どうみても決定不能です。本当に(ry
コンパイラの最適化ってのは、 大抵問題が決定不能だから近似解を求めるものですがなにか
Cleanでは、20の内容がそのまま実装されている。 だから速い。
23 :
デフォルトの名無しさん :2006/06/04(日) 18:13:26
じゃあ何故クリーンではなくはすけるのだ?
24 :
デフォルトの名無しさん :2006/06/04(日) 18:59:31
遅延評価のIOとかが便利にできるかが問題だとすればCleanも十分不便だし、 GHCは正則評価できる。
25 :
デフォルトの名無しさん :2006/06/04(日) 19:54:05
前スレ
>>973 なんでIOモナドの話に世界を持ち出したらダメなの?
なんかの論文にも出てた気がするけど。
concurrencyのせい?Concurrent Haskellの論文にはπ計算とか出て来て正直分からん。
(ふつけるまだ読んでない私が言うのも何だけど
type IO a = State World a みたいな感じの理解でとりあえずおいとくのはアリだと思うんだけど。
>>25 大体次のような感じ。concurrencyは念頭になかった。
・どこかでHaskellレベルの概念と実世界の概念を対応させなきゃいけない
(Worldを持ち出しても、World -> Worldの関数が実世界の何に対応するかを
説明しなきゃいけない。(*1))んだから、余計なものを持ち込まない方がいい。
・IO aには十分簡単な説明(「a型の値を返すアクション」「無引数でa型の値を返す
(Cの)関数へのポインタ」)があって、実例もあげやすいのに対し、世界はそうではない。
例えば、この本ではアクションが起こる順番が定まっていることを各中間世界の依存性から
言っているけど、それぞれの中間世界の値が(計算で?)決定されることと、
一つしかない実世界の状態が変化することの関係が不明瞭。
しかし、考えてみると、初めて世界を使ったIOモナドの説明を読んだとき
全然納得できなかったことの腹いせのような気もしてきた。
不必要にきつい表現を使ったことをお詫びします。
*1: ただし、この本ではアクションがWorld->Worldの関数だとは言っていないし、
世界を表す値があるとはっきり言っている訳でもない。
> IOモナドは概念的に「まだ入出力を実行していない現実世界」をアクションの中に包み込んでいます。
丁寧な返答どうもです。 いや、作者さんじゃないしお詫びされる程じゃないっす。 確かに「世界」と言われても腑に落ちない人も居るかもしれない。 ところで評価順の話ですが、 私、評価順がどうなってるのかなんてよく分かってません(--; do x <- return (f v) print $ g w print $ x この場合、観測できるのはg wの印字とf vの印字だけど、 実際はどっちが先に評価されるんだっけ。 例えば、f vが head []を含んでいた場合、g wは印字されるか? …やってみた。 Prelude> return (head []) >>= \x -> print "hoge" >>= \_ -> print x "hoge" *** Exception: Prelude.head: empty list IOアクションに渡される引数の簡約が、評価順のトップになるという感じなのかな。 (わかりにくい説明でスマソ)
>>27 Tackling the awkward squad
http://research.microsoft.com/~simonpj/papers/marktoberdorf/mark.pdf にIOモナドの意味論が載ってる。いい加減に要約すると、
1. プログラム全体を>>=のチェーンで表す
2. チェーンの左端を次に何をするか判明するまで簡約する
3. チェーンの左端を実行し、チェーンから取り除き、実行結果を右辺の関数に食わせて新たなチェーンを作る
4. 2に戻る。
という感じかな。
その例だと、
return (head []) >>= \x -> print "hoge" >>= \_ -> print x
-- 左端を簡約。ここではなにもしないでおく。
return (head []) >>= \x -> print "hoge" >>= \_ -> print x
-- 左端を実行。returnだからなにもしない。結果は(head [])
print "hoge" >>= \_ -> print (head [])
-- 左端を簡約。この結果putChar 'h' >>= \_ -> putChar 'o' >>= \_ -> ...
-- のようなものができると考えられるが、ここでは省略する
print "hoge" >>= \_ -> print (head [])
-- 左端を実行。hogeと出力。結果は()
print (head [])
-- 左端を簡約。ここでエラー発生。
29 :
27 :2006/06/04(日) 22:25:59
ありがとう。まさしくその論文ですねWorldが出てくるのって。 Cleanとかの"world as value"という感じ?
>>27 のdo記法版を見て期待してしまう動作は最初のx <- return (head [])でエラー発生なんだけど、実際にはそういう風にはならないのか。
let x = head [] だったりすると余計にそう考えてしまうんだけど、実際にはx <- return (head [])とまったく同じでした。
逆にprint "hoge"の前にxを評価してエラーを発生させるためにはどうすればよいのだろう。
一応seq x (return ())を入れてやればエラーが起きたけど、もっと別の方法はないのかな?
Control.Exception.evaluate x とか。
>>31 Hoogleで検索して結局それに行き着きました。
returnの代わりにevaluateを使えば良いから、変な行を追加する必要が無くてすっきりしますね。
33 :
デフォルトの名無しさん :2006/06/05(月) 04:53:12
私たちは素晴らしいモナドのモナドのモナドのモナドのモナドのモナドのモナドの中にいる。
それにしても、日本語の本が出た影響ってすげぇな。 いきなり過疎スレが復活してるし。 ネットでいろんな文章見かけるようになった。
amazonこねーーーーーー 配送予定日: 2006/6/3 - 2006/6/4 今日は6月5日だ( ゚Д゚)ヴォケ!!
いいか、みんな (゚д゚ ) (| y |) amazonで注文すればokと信じていたのに、 いつまでたっても商品が来ない。 amazon ( ゚д゚) ok \/| y |\/ これらをくっつけて ( ゚д゚) amazonok (\/\/ 逆から読むとこのざま、というわけだ ( ゚д゚) konozama (\/\/ amazonは当てにならない、ということだな (゚д゚ ) (| y |)
38 :
デフォルトの名無しさん :2006/06/05(月) 15:30:16
自作関数が既存の物よりどれほど低速か知りたいのですが 所用クロックなんかを教えてもらうにはどうすればいいですか?
つーか本屋でもみかけないんだが、本当に発売されてる?
40 :
デフォルトの名無しさん :2006/06/05(月) 16:08:44
渋谷のブックファーストで1時間探したが無かった 入門〜はあった
>>38 :set +s
GHCでは時間と使用メモリ、Hugsでは使用セル数と簡約回数がわかる。
ただ、GHCの使用メモリ量は、同じ式を評価してもコロコロ変わる……
中野のあおい書店には両方十冊くらいあった。
GHCで-prof -auto-allオプションをつけてコンパイルして、 +RTS -pオプションをつけて実行ファイルを走らせれば 実行ファイル名.profに各関数の使用時間とかが出力される。 でも、Hugsで調べたほうが手間が少なくてよいかも。
hugsで ERROR - Garbage collection fails to reclaim sufficient space のメッセージがでちゃうと以後何を評価しても同じメッセージがでてしまいます この場合再起動するしかないのでしょうか? hugsのバージョンはZaurs版の hugs98_Mar2005-patched-1_arm.ipkです。 プロンプトまで戻ってきていてGC不可能ってことは最後に評価してある式はまだ評価途上のままのこってるってこと?
>>44 バグなんじゃないか?
手元のHugs March 2005(Linux/x86)だとそのメッセージが出た後も普通に使える。
それから、役に立つかどうか分からないけど、Hugsには:gcというコマンドがある。
46 :
45 :2006/06/05(月) 19:05:11
ごめん。
>>45 は忘れてくれ。再現できた。
k = [1..]
と書いたスクリプトを用意して、
length k
を評価するとそうなるな。
47 :
45 :2006/06/05(月) 19:10:29
>>46 追試ありがとうございます。
zaurus固有ならコンパイル環境そろえて自力で最新版とか考えたのですが違うみたいですねぇ。
49 :
デフォルトの名無しさん :2006/06/05(月) 19:14:51
うわしまったこれじゃ stack overflowまでループじゃん…って時は どうやって停めますか?
>>47 あう、重ねがさねありがとう。
まさに無限リストいぢくってる最中だったので、ビンゴっぽいです。
51 :
デフォルトの名無しさん :2006/06/05(月) 20:31:20
この関数型言語ってほんとおつむの良し悪しが出るね 慣れてないからかね
ちょっとパズル的なところがあるからじゃないかな。 道具がprimitiveすぎるからだと思うんだけど。 C++ templateも近いものがある。
というかここに居る人たちレベル高すぎて・・・ 恥ずかしくてレベルの低い質問も出来ないよw
せっかく2chにHaskellのスレがあるのにろくに活用されてないのは悲しい。 ということでレベルの高低にかかわらずどんどん質問するべきだと考える。 俺に答えられることなら喜んで答えるので。
日本語のHaskellの本を書いている人の日記を見ても、 あんまり大した情報が書かれて無いね。 Webに書いてもお金にならないからかね。
君のレスが面白くないのもお金(ry
58 :
デフォルトの名無しさん :2006/06/06(火) 08:07:02
くだすれHaskell(超初心者用) 立ててくれ
【ネタ心物歓迎】ハスケル質問箱 for Perler 立ててくれ
60 :
デフォルトの名無しさん :2006/06/06(火) 10:58:09
div 整数 整数 ってひょっとしてちゃんと約分までしてくれる?
結果も整数だから約分は関係ないんじゃないか?
62 :
デフォルトの名無しさん :2006/06/06(火) 11:28:37
fact n = product [1..n] Conbi n r = (fact n) `div` ((fact r)*(fact (n-r))) したらなんか結果が優秀なんだけど 途中計算で約分してるとしか思えない
>>62 オーバーフローしてないって事?
それなら単に整数のデフォルト型がInteger(無限長整数)だというだけの理由。
試しに
fact :: Int -> Int
とでも書いてInt(固定長整数)を使うように指定してやれば、ちゃんとオーバーフローするはず。
64 :
デフォルトの名無しさん :2006/06/06(火) 12:00:26
約分じゃなくて、 deforestrationしていたら面白いのにな。
haskell勉強して、なんかいいことあるの? 人に自慢して、うっとうしがられるくらい?
>>65 って生きていて、なんかいいことあるの?
人に、うっとうしがられるくらい?
研究者とかならあるんじゃね?
そんなの自分で考えなでしょ。 言語マニアも居れば、遥かに先を見ていて、通過点と考えてる人も居るだろうし。
「入門Haskell」と「ふつうのHaskell入門」の両方買ったんだけど、 正直「ふつう」の方が読みやすい。 特に序盤。「入門」はいきなりおいてけぼりを食らった気がした。 「ふつう」の方はわざわざ式を展開してくれるとか丁寧。 もう関数型言語を理解してる人にとっては、 「そんな方法でページ稼ぎやがってー」と思われるのかもしれないけど、 勉強し始めの身にはありがたい。 いい入門書だと思う。
対象読者が違うってことなのかな? 色んな対象への本があるってのはいい事だと思う。
73 :
デフォルトの名無しさん :2006/06/07(水) 06:42:15
Visual Haskellなんてのがあるんだな。 商用アプリは製作禁止だっけ?
74 :
デフォルトの名無しさん :2006/06/07(水) 12:59:17
ghciで深刻でないバグを見つけた。 インタプリタに処理させた後で 上押してさっきの入力を呼びだしてそれを繰り返し処理 高速に繰り返すと <interactive>:1:0: Notin scope: `g〜' ってエラー起こす。 g〜ってのは、関数名の先頭一文字めだけgになった関数名にバグ表記という意味 sum -> gum
75 :
デフォルトの名無しさん :2006/06/07(水) 16:04:21
第一引数のリストから、第二引数のリストとで重複する要素を取り去ったリストを得る 高速な関数ありますか?
my@ARR1=(0,1,2,3); my@ARR2=(1,2); my@TMP=grep {my$ARR1=$_;!grep{$ARR1==$_}@ARR2}@ARR1; print "@TMP\n";
頭のおかしい方がいます
( ´,_ゝ`)プッ こんな簡単な関数も書けないくせに偉そうにw
Visual Haskellなんだが、インスコできなかった。 Visual Studio2005だとダメっぽいな。
頭のおかしい方がいます
>>79 どうもそうらしいね。俺の知り合いもそう言ってた。2003でないとダメぽ
Haskell.NETはどうなったんだ? STL/CLI(旧STL.NET)は使えるのか?
>>75 第二引数のリストに Eq 以外に Ord などの特徴があれば、
二分木やハッシュにしておけば速くならないかな?
87 :
デフォルトの名無しさん :2006/06/08(木) 02:16:43
遅延評価ってスレッドみたいなもん?
最近おぼえた言葉をとりあえず繋げてみるのはやめような。
89 :
デフォルトの名無しさん :2006/06/08(木) 02:57:52
ごめんなさい。。。 遅延評価ってオンザフライみたいなもん?
まぁ、ニュアンス的にはそんなもんかな
91 :
デフォルトの名無しさん :2006/06/08(木) 03:30:42
遅延評価=つん読
92 :
デフォルトの名無しさん :2006/06/08(木) 05:44:29
遅延評価によるプロセス切り替えのオーバーヘッドがクリティカルな場合 バッチ処理的にやりたくなったら、遅延評価をしないという選択はできるのですか?
>遅延評価によるプロセス切り替え なにこれ
94 :
デフォルトの名無しさん :2006/06/08(木) 06:18:32
プロセスっていうか 必要な分が揃ったら処理とかやってくわけですよね? 関数のバケツリレーで あの関数を処理してちょっと停めてこっちの関数移ってとか 切り替えにオーバーヘッド時間かかると思うのです
日本語でおk
>94 とりあえず遅延評価でググって上から順に見てってみろ。
>必要な分が揃ったら処理とかやってく どうみても理解してません本当に(ry
98 :
デフォルトの名無しさん :2006/06/08(木) 14:43:13
><
>>=
ちょwww
必要になったら使うってことでよい? 式なんだけど、関数ポインタ渡すみたいな
> 関数ポインタ渡すみたいな 違うか。匿名メソッドを渡すみたいな幹事なんだろうか
>>75 今頃だけど notElemってのがあった
diff xs ys = [x | x <- xs, notElem x ys]
>>103 遅延評価=その場で評価されないって意味で書いた
import List main = print ([1,2,3,4,5] \\ [2,3,4])
>>105 「何」が「どの場」で評価されないと?
何か聞きたいなら他人に判るように(出来るだけ厳密に)書いてくれ。
なんにせよ、「必要になるまで使わない」のはHaskellに限らず当り前。
>>102 それは(実装の意味で)かなり正しい。例えば有名なたらいまわし関数を
遅延評価を意識して C++ で関数オブジェクトっぽいものを使いながら書くと
こんな感じになる。悲惨なほどメモリリークするのは許して。
struct Object { virtual int eval() = 0; };
struct Const : public Object {
int x; Const(int x) : x(x) { } int eval() { return x; } };
struct Tarai : public Object {
Object *x, *y, *z;
Tarai(Object *x, Object *y, Object *z) : x(x), y(y), z(z) { }
int eval() {
int xval = x->eval(), yval = y->eval(), zval;
if (xval <= yval) { return yval; }
else {
zval = z->eval();
Tarai *tx = new Tarai(new Const(xval-1), y, z),
*ty = new Tarai(new Const(yval-1), z, x),
*tz = new Tarai(new Const(zval-1), x, y);
Tarai tot(tx, ty, tz);
return tot.eval(); } } };
int main() {
Tarai tarai(new Const(48), new Const(24), new Const(0));
printf("%d\n", tarai.eval());
}
すまん、挙動が違った diff [1,2,3,4,2,3,4,5] [2,3,4] => [1,5] (\\) [1,2,3,4,2,3,4,5] [2,3,4] => [1,2,3,4,5] (\\) [1,2,3,4,2,3,4,5] [2,3,3,4] => [1,2,4,5] どっちにしろこれ自体が遅いのかもしれないけど
実装って事はメタレベルの話だからまったく違うだろと 同じレイヤーで話せっての
私は遅延評価の「実装」の話を尻鯛です。グラフリダクション? 手元にPeyton JonesのImplementingとImplementation of Functional Programmingの本があるんだけど 1990年とかで古過ぎ。 GHCはどんな風にコンパイルしてるのか,それなりにまとまった読み物はない?
まじすか。どうもありがとう!
今見たら Implementation ... は 1987, Implementing...は1992だった。
多分
>>113 のやつだと思う。ちゃんと読んでみますです。。
>>112 遅延評価の実装をまったく知らないなら、
GHC に興味を持つ前に SICP でも見て自分で実装してみたほうがいいと思う。
SICP 読まなくても、scheme の promise の仕組みを知ってれば、実装は出来る。
116 :
デフォルトの名無しさん :2006/06/09(金) 00:19:31
遅延評価のせいでやたら処理が遅くなってる場合はモナドですか?
117 :
デフォルトの名無しさん :2006/06/09(金) 00:23:48
やっぱり くだすれHaskell(超初心者用) のスレ立てが急務だ。 おまいら正直あまりにとんちんかんで低レベルな質問が増えて 辟易してるだろう?
118 :
デフォルトの名無しさん :2006/06/09(金) 00:24:48
そんな事書いてる暇があれば立てろという突っ込みは受理しません
まあでもなんだかんだでそっちも見て結局辟易するんじゃね?
>>116 (IO以外の)モナドと遅延評価は関係ない。
Stateモナドでスライド辞書書いてみて
身にしみた。
浮動小数演算遅せー IORef遅せー String遅せー うおぉぉぉ
122 :
デフォルトの名無しさん :2006/06/09(金) 06:53:00
ハスケル製アプリで金取るの駄目?
123 :
デフォルトの名無しさん :2006/06/09(金) 07:53:35
型クラスに関わる(型)推論がどのようになされるのか解説はありませんか? ちょっとちがうのかもしれないけど、型変数同士がうまく単一化されてくれないんです… どちらにせよ、fundepsとかmultiparameter type classがどんな風に計算されるのかを ちゃんと知っておきたいんですが。
私が持っているコードは以下のような感じです。 インデントが全角スペースになっているので注意してください。 class Stateful c s where conv :: c -> State s () instance Stateful (State s ()) s where conv = id instance Stateful (s->s) s where conv f = State (\s->(f s, ())) foo :: State s () foo = return () bar :: s -> s bar = \s -> s act :: Stateful c s => c -> State s () act c = conv c hoge :: State s () hoge = do act foo act bar
うごごご…全角スペースになってませんでしたorz で,ここで test1.hs:45:2: No instance for (Stateful (State s1 ()) s) arising from use of `act' at test1.hs:(act fooの行):2-4 Probable fix: add (Stateful (State s1 ()) s) to the type signature(s) for `hoge' or add an instance declaration for (Stateful (State s1 ()) s) In a 'do' expression: act foo In the definition of `hoge': hoge = do act foo act bar test1.hs:46:2: No instance for (Stateful (s1 -> s1) s) arising from use of `act' at test1.hs:(act barの行):2-4 Probable fix: add (Stateful (s1 -> s1) s) to the type signature(s) for `hoge' or add an instance declaration for (Stateful (s1 -> s1) s) In the result of a 'do' expression: act bar In the definition of `hoge': hoge = do act foo act bar と言われます… foo の型変数sと hogeの型変数sが単一化できてない感じです。
あ, class Stateful c s | c -> s where で行けましたOTZ まあでも情報きぼんぬです
>>122 もちろん問題無いが、おまいには金を取れそうなアプリなど作れないだろう
129 :
デフォルトの名無しさん :2006/06/09(金) 11:56:30
>>127 シェアウェアとかおkなんですか?
夢広がりんぐ
vipperには無理だろ、お祭り意識がなくなったらやる気なくしちゃうんだから。
その前に知能が(ry
132 :
デフォルトの名無しさん :2006/06/09(金) 14:44:09
遅延評価ってバッチ処理より処理終了が遅れますよね?
ttp://headlines.yahoo.co.jp/ranking/php/book/pc.html PHP研究所
コンピュータ(書泉グランデ調べ 2006年5月29日〜6月4日 ) 毎週水曜日6時 更新
* 『ふつうのHaskelプログラミング』第1位!
* 『ウェブ進化論』第2位!
順位前週書名著者出版社価格
1-ふつうのHaskelプログラミング ソフトバンククリエイティブ2800円
2-ウェブ進化論 筑摩書房740円
31組込みプレス Vol.3 技術評論社1680円
4-グーグル明解検索術 宝島社700円
5-Asterisk-テレフォニーの未来 オライリー・ジャパン3800円
6-Fedora Core Expert Vol.2 技術評論社1980円
7-Fedora Core 5で作る 最強の自宅サーバ ソーテック社2780円
8-グーグル Google 文芸春秋760円
9-LATEXを用いた論文作成術 プレアデス出版2300円
10-The Debian System その概念と技法 毎日コミュニケーションズ5200円
11-プロとしてのOracle PL/SQL入門 ソフトバンククリエイティブ2400円
12-ITエンジニアのためのコミュニケーション能力診断 ソフトバンククリエイティブ1740円
13-Google誕生 イースト・ブレス2286円
14-明解入門 Visual C++2005 ビギナー編 ソフトバンククリエイティブ3800円
15-Open Office.org 2.0 オフィシャルユーザーズガイド 毎日コミュニケーションズ2500円
16-図解でわかる Ajaxのすべて 日本実業出版社2000円
17-Javaのココロ ソフトバンククリエイティブ1800円
18-TRONWARE Vol.99 パーソナルメディア1200円
19-XOOPS Cube 使いこなしガイドブック ローカス2800円
2016ひと目でわかる Microsoft SQL Server 2005 日経BPソフトプレス2400円
理解できないのに買う見栄っ張りがそれだけ多いということだな
いやあ、理解できるでしょう。がんばれば。 C系以外を使った事が無いと、なかなか目が慣れない、ということはあると思うけれど。
>>134 書籍ビジネスは本棚に本を並べることを趣味とする人たちがターゲットですよ
Haskellをステータスだと思う人が増えただけでも良いかと 知名度も上がるだろうし
TRONWARE が18位なことに驚き
GHCが人手を募集している。
140 :
デフォルトの名無しさん :2006/06/10(土) 07:00:22
Haskellが万能だと思ってる俺の熱を冷ましてくれ。 いつもHaskellの事を考えてしまって生活が破綻する。
コンパイラの実装を把握していて、pros/cons を分かった上で使ってるなら良いんじゃないの。 もしそうなら、Haskell が万能というよりは貴方が万能な訳だ。
O(N^3) の対角化ルーチン書いて。
143 :
デフォルトの名無しさん :2006/06/10(土) 13:21:07
Haskellおもすれー(^ω^ )
>>143 λ,,,,,,λ ガオー!
∩`iWi´∩ λ,,,,λ グオー!
ヽ |m| .ノ∩`iWi´∩
|  ̄| ヽ |m| .ノ
| | | |
U⌒U U⌒U
>>140 Cに遜色ないくらい高速にアクセスできるHashtableを実装してみてくれ。
146 :
デフォルトの名無しさん :2006/06/10(土) 14:02:13
lastの実装とか馬鹿臭くないですか? 先頭から辿るなんて。 単調減少リストをクイックソートする最悪ケースがあったとして 遅延評価なら結果リストの最後の要素はすぐ返せると思いきや、 lastは初めから辿る実装なので、結局リストの初めが出来上がらないことには動き出せないわけで 則ちこのケースではリスト完成するまで待たされるという事じゃないですか! プリミティブな関数程綿密に設計されなければならないとい事ですか?
>>146 それはlastの問題じゃなくて、Haskellのリストが単方向リストであることの帰結。
148 :
デフォルトの名無しさん :2006/06/10(土) 14:26:41
両方向リスト作れって事ですか?
150 :
デフォルトの名無しさん :2006/06/10(土) 14:59:46
lastなんてたかだかO(n)の処理。どうでも良い。
152 :
デフォルトの名無しさん :2006/06/10(土) 18:54:19
ふつうのHaksell買ったけど特に説明うまいとは思えんかったな
はじめに出たやつよりはましだろ。
154 :
デフォルトの名無しさん :2006/06/10(土) 21:01:16
Haskellの勉強しようとすると、Clara Haskilのレコードを聴きだして勉強が進まない。
155 :
デフォルトの名無しさん :2006/06/10(土) 21:06:13
なんかフジテレビに白石ひよりが出てるな
>>152 > ふつうのHaksell
それ、パチもんだから。
最低限の代数学のセンスないとダメだから。 無理だと思った人はとっととあきらめて。
>>154 Haksellができたところで現実的には何も変わらんから気にするな
159 :
デフォルトの名無しさん :2006/06/11(日) 03:10:22
変わらないなら変えるんだ!
160 :
デフォルトの名無しさん :2006/06/11(日) 05:10:03
関数型言語やってると脳が活性化しますね。 物事を再帰関数で考える所も、ワーキングメモリ増強に良い気がします。
161 :
デフォルトの名無しさん :2006/06/11(日) 05:11:53
concatってなんて発音するの? コンキャット?
162 :
デフォルトの名無しさん :2006/06/11(日) 07:10:38
辞書引きなさいよ
163 :
デフォルトの名無しさん :2006/06/11(日) 07:35:31
分からないなら黙ってなさいよ
分かってる人も答えなさんなよ
>>160 再帰で考える方がワーキングメモリは少なくて済むんじゃないか。
166 :
デフォルトの名無しさん :2006/06/11(日) 10:16:56
>>165 俺は最初再帰関数の処理手順がイメージつかなくて脳が悲鳴を上げた
脳にスタックを作るのはいい体操になると思う
小学生ですが、小学生でも理解できるでしょうか?
出来ない理由はない。
このスレ住人に理解できることが小学生に理解できないわけがないだろ。
170 :
デフォルトの名無しさん :2006/06/11(日) 11:56:23
このスレに東大生はいますか?
何で東大生を探しているの?
どうもこの瞬間にはいないようです。
BBSのログは一つだけだから、瞬間には唯一人しかいないに決まってる。
175 :
デフォルトの名無しさん :2006/06/11(日) 13:33:32
諸君、議論したまえ。
もうすることないです
177 :
デフォルトの名無しさん :2006/06/11(日) 15:10:26
Haskell製のテキストエディタあったろ あれいじってなんか書け
Haskellって案外生産性が低いんだよな。 Pythonと比べて30倍くらい時間かかる。
VBの方が生産性高いよね。すぐに動くコードが出来上がる。
181 :
デフォルトの名無しさん :2006/06/11(日) 16:47:36
BASICより遅いよな、ぶっちゃけ。 まあその代わり素晴らしい表現力があるが。
haskellの最大の欠点(つかocamlもなんだけどよ) unicode対応まだ〜?チンチン!!(AA略)
ocaml日本語使えるじゃん
>>183 # ["漢字文字列"] ;;
- : string list = ["\138ソ\142\154\149カ\142\154\151\241"]
↑これを使えるっていうのならね
>>157 何の煽りか知らないけど、
代数学の知識なんて要らないんじゃ?集合論の知識すら要らないような。
モナドの話になるとちょっと代数が関わってくるけど,Haskellerならreturnが単位元な事と>>=の結合則が成り立つ事が分かっていればいい。
Haskell は
・マニュアルの読み方
・データと型の名前空間が違うということ
・構築子は大文字で,関数や型変数は小文字だということ
・演算子の中置記法
・let文の書き方
・パターンマッチの使い方
・型構築子の概念 (Either a bは a と b の 二つの「型引数」を持った型,とか)
・IOモナドの使い方 (>>=とreturnの型が分かること)
これだけわかればとりあえず使えるはず。(常識的なC,Javaに慣れていれば)
高階関数なんかは頭をひねってくれ。lisp/schemeでも使うでそ。
特に IOモナドは,数学の概念とかは忘れて,単に (>>=) :: IO a -> (a -> IO b) -> IO b を (先にやるアクションA) >>= (Aの戻り値を受け取り,次にやるアクションBを返す関数) == Aの次にBを行うアクション という風に理解できればOK。 細かいサブルーチンを組み合わせて大きなサブルーチンをつくるのが >>=という演算子。 例えば myprint str = putStrLn str getLine >>= myprint は, getLine >>= \str -> myprint str と同じで,do構文なら, do str <- getLine myprint str ということ。ただこれだけ。
>>185 > Haskellerならreturnが単位元な事と>>=の結合則が成り立つ事が分かっていればいい。
代数じゃん!
>>184 wwwwwwwwwwwwwwwwwwww
> >>=の結合則 別に成り立たなくてもプログラムの意味は変わらないと思う
do do a b c と do a do b c で意味が違うのは嫌じゃないか?
>>188 何わらってんだかしらんが、一文字を一文字として扱えない段階で話にもなってないって事じゃねぇの?
日本語なんて使うなよ それとも英語も出来ない人ですかw
196 :
デフォルトの名無しさん :2006/06/12(月) 01:22:59
you can do shityainayo
197 :
デフォルトの名無しさん :2006/06/12(月) 06:36:21
$! でバッチ処理的にソートさせてみたら、 なんと遅延評価させるものより遅くなった! 死にたい
>>187 自分で一からモナドを書かない限り、代数は使わなくても済むよ〜、
と言いたかった。
もちろん知っておいた方がいいのは間違いない。
他にfoldrとfoldlは与える演算子が結合的なら結果が同じになるとか。
ただ普通にCやJavaでやっていた計算をHaskellでやる分には何も考えなくても書ける。
199 :
197 :2006/06/12(月) 06:59:15
しかもメモリ馬鹿食いしてる!
201 :
デフォルトの名無しさん :2006/06/12(月) 11:29:15
手軽にランダムリスト得たい時はどうしますか?
Haskellで乱数は使ったことなかったのでちょっと試しに書いてみた。 module MyRandom where import System.Random import System.Time import System.IO.Unsafe getPicosec :: IO Integer getPicosec = getClockTime >>= return . ctPicosec . toUTCTime newStdGenFromClock :: IO StdGen newStdGenFromClock = getPicosec >>= return . mkStdGen . fromInteger randomsRIO :: Random a => (a, a) -> IO [a] randomsRIO = (newStdGenFromClock >>=) . (return .) . randomRs -- randomsRIO r = newStdGenFromClock >>= return . randomRs r randomsIO :: Random a => IO [a] randomsIO = newStdGenFromClock >>= return . randoms randomsRUnsafe :: Random a => (a, a) -> [a] randomsRUnsafe = unsafePerformIO . randomsRIO randomsUnsafe :: Random a => [a] randomsUnsafe = unsafePerformIO randomsIO これをインポートして take 10 $ randomsRUnsafe (0, 5) とかすれば乱数リストが取れた。
203 :
デフォルトの名無しさん :2006/06/12(月) 14:24:32
204 :
デフォルトの名無しさん :2006/06/12(月) 17:19:48
>>202 randomsRUnsafeをtakeするのをreplicateしたら全部同じリストなんですね。
nobsunの ハッカーがHaskellを使うべきでない10の理由 超ワロス
206 :
202 :2006/06/12(月) 19:06:14
>>204 それはしょうがないんじゃないかと思う。
それはそれとして、
sequence $ replicate 10 $ randomsRIO (0,5) >>= print . take 15
とかやっても高々2種類でしたよ(^^;
まぁ、picosecの値が同じ間は同じ列になるわけだから当然の結果だけど。
とりあえず下のようにgetStdGen, setStdGenを利用してやるようにしたら毎回違う列になるように出来た。
newStdGenFromClock
= do { i <- getPicosec; j <- getStdGen >>= return . fst . random;
setStdGen $ mkStdGen $ fromInteger i + j; getStdGen }
>>191 Hugsだと
Hugs.Base> "あいうえお"
"\12354\12356\12358\12360\12362"
になる。
でもロケールのエンコーディングに変換されるのでUnicode環境じゃないときびしい。
208 :
207 :2006/06/12(月) 19:24:48
>>191 ×でもロケールのエンコーディングに変換されるので
○でも入出力時にロケールのエンコーディングに変換されるので
>Unicode環境じゃないときびしい。 なんで?どこでも使えるためのlocaleだと思うんだが。
>>207 WinHugsだと
Hugs> "あいうえお"
"\642554146"
になる。
どう見てもバグ。
>>210 WinHugs付属のhugs.exeだと
Hugs> "あいうえお"
"\130\160\130\162\130\164\130\166\130\168"
だったり。
lengthに関してはどっちも
Hugs> length "あいうえお"
10
まぁ、putStrで表示してくれるからとりあえずは使える。(GHCみたく構文解析レベルではねられるよりはマシ)
Hugs> putStr "あいうえお"
あいうえお
Linux Hugs.Base> putStr "あいうえお" あいうえお Hugs.Base> length "あいうえお" 5 Hugs.Base> "あいうえお" "\12354\12356\12358\12360\12362"
213 :
デフォルトの名無しさん :2006/06/13(火) 07:31:40
haskellのメッキは剥がれるのか?
sampou.org のデータがふっとんだんだね。 日本の Haskell の普及に貢献したことは忘れない。合掌。
215 :
デフォルトの名無しさん :2006/06/13(火) 14:13:11
仕様変更がある内はHaskellで 仕様確定して仕上げる時に、速くしたい部分をC++で って感じで構築すればおk?
>>214 一部wget -mしたもの持ってるけどなにか役に立つかな?
>>205 OSMのやつ?
タイトルが気になったから、立ち読みして来た。
けど、私にはつまんなかった。
何が言いたいのか、わからんかった。
218 :
デフォルトの名無しさん :2006/06/14(水) 12:12:35
多相的な関数について、型変数が特定のクラスのインスタンスであるかどうかによって 実装を切替えることってGHC拡張の範囲でできる?
219 :
デフォルトの名無しさん :2006/06/14(水) 12:23:41
普段は線形探索だけど、Ordのインスタンスに対しては二分探索を使う、とか。 -- Ordのインスタンス用実装 containsOrd :: (Ord a) => [a] -> a -> Bool containsOrd xs = \y -> ... table上の二分探索 ... where table = array ... 配列を構築 ... -- それ以外用実装 containsOther :: (Eq a) => [a] -> a -> Bool containsOther = flip elem contains :: (Eq a) => [a] -> a -> Bool contains = ... aがOrdのインスタンスならcontainsOrdを、そうでないならcontainsOtherを呼ぶ ... でも実装を考えてみたら渡すべき辞書がないから無理だな。 どっちにしてもレスありがとう。
コンパイル時切り替えなら、 C++風の、特殊化とtype traitsで出来るんじゃないか?
>>221 型クラスは実行時解決だからな。
型クラスで書いてると、ときどき全部Template Haskellで書き直したくなる。
Template Haskell良さそうね。 型や宣言を書き換えられない([d||]の中に$()が書けない)のがアレだけど。
224 :
デフォルトの名無しさん :2006/06/14(水) 22:16:14
すみませんが、質問です。 無名関数を演算子的に中置記法で使うことは出来ないのでしょうか? *Main> 2 `(x y -> x + y)` 3 <interactive>:1: parse error on input `('
>>224 バッククォートで囲めるのは単一のトークンだけ。
226 :
224 :2006/06/14(水) 22:23:23
おお、そんな制約が。 では出来ないのですね。ありがとうございました。
the Reportじっくり追えば分かるね。
>>223 >型や宣言を書き換えられない([d||]の中に$()が書けない)のがアレだけど。
$(..)が書けないのは型宣言だけかと? 宣言に対して [|d hoge = $(...)|] は書けるっぽい。
確かに[d| data S = $(...) |]は無理。
┏┳┳┓ ┏┳┳┓ ┏┫┃┃┃ スレ違い雑談は┃┃┃┣┓ ┃┃┃┃┣┓ ここまで.┏┫┃┃┃┃ ┃ ┃┃┏━━━┓┃┃ ┃ ┃スレ違い ┣┫ ・∀・ ┣┫ END ┃ ┗━━━━┛┗┳━┳┛┗━━━━┛ ┏┻┓┃ ┏━┛ ┣┻┓ ┗━━━┫ ┗━┓ ┗━━━┛
230 :
デフォルトの名無しさん :2006/06/15(木) 12:08:16
すみませんが、質問です。
下のページを参考にしているのですが、関数の合成がうまく行きません。
http://www.shido.info/hs/haskell3.html 何故なのでしょうか?
foo x y = x * y
bar x = x - 1
*Main> bar $ foo 5 2
9
*Main> (bar . foo) 5 2
<interactive>:1:
No instance for (Num (a -> a))
arising from use of `bar' at <interactive>:1
In the first argument of `(.)', namely `bar'
In the definition of `it': it = (bar . foo) 5 2
>>230 (.)は一引数の関数しか合成できない。
233 :
230 :2006/06/15(木) 13:07:17
報告しといた。
>>230 (.) :: (b->c) -> (a->b) -> a -> c
なので、bar . foo とするとbarとfooはそれぞれ1引数関数として扱われる。
barはもともと1引数なので問題ないが、fooは2引数関数( n -> n -> n )なので、
1引数関数を返す1引数関数( n -> (n -> n) )と解釈される。
その上で(.)の型に当てはめていくと、
barから、b=n, c=n
fooから、a=n, b=(n->n)
となり、bに関して矛盾が起きる。
実際にはbarの型は少し幅があるのでb=c=(n->n)として当てはめようとするんだけど、
(n->n)はその許された幅からも逸脱しちゃってるよ、とエラーメッセージを出している。
>>232 curry, uncurryを使わなくても、 (bar .) . foo でOK。
ちなみに、fooが3引数だと、 ((bar .) .) . foo でOK。
237 :
232 :2006/06/15(木) 15:15:22
な、なんだっ(ry
239 :
デフォルトの名無しさん :2006/06/15(木) 20:10:31
$ってなに?
>>239 関数適用演算子。
f $ x = f x
右結合で優先順位0の演算子なので、括弧を省略するのに使える。例えば、
length $ filter null $ lines str
は、
length (filter null (lines str))
と同じ。
論理学での記述でいうドットかな。
Template Haskellの話題がスレ違いだとはorz あと map.mapとか bar.foo とか、 (.) を使う時にスペースを入れないのは流行なの? パッケージ名の修飾と間違えそうで怖いんだが。 hoge.hs: data Data = Data Int fun x = x+1 ghci/hugs> hoge = Data.fun このData.funはモジュールDataの関数funなのか Data . fun なのか判別できるのか? やってみた。 *Main> let x = (Data.fun) 1 <interactive>:1:9: Failed to load interface for `Data': Could not find module `Data': it is not a module in the current program, or in any known package. *Main> let x = (Data . fun) 1 結論:中置演算子の . は離して書くこと。ってReportかGentle〜に書いてあった気がするけど。 $も同様。 $(...) は -fth で template haskellのspliceと間違える可能性がなくはない。 $ (...)とする。
243 :
デフォルトの名無しさん :2006/06/16(金) 08:32:50
ジュンク堂池袋本店、ふつケルと入門Haskellが並んで平積み、は いいのだが…… POPに描かれている「はすケロ」なる、蛙と思われるキャラの絵は何だ。
245 :
デフォルトの名無しさん :2006/06/16(金) 14:10:26
プリミティブですみませんが、質問です。 my_length [] = 0 my_length (x:xs) = 1 + my_length xs ここで、x:xs が()で囲われなければならないのはなぜでしょう? 私は「:」演算子が関数適用より優先順位が低いからだと思っていたのですが、 どうも違うような気がしてきました。 そもそも「:」はデータコンストラクタだということで、「ふつケル」の7章と 9章を見てみたのですが、()についての記述は見つかりませんでした。
248 :
245 :2006/06/16(金) 15:20:27
>>247 なるほど!ありがとうございます。
演算子の優先順位の問題なら、()の代わりに$が使えるはずだと思っていたの
ですが、それはエラーになってしまったので、間違いだったかと思い始めまし
た。
そうではなくて、パターンマッチに$が許されないからだったのですね。
>>242 関数は小文字から始めることになっているから問題ない。
Dataという関数はありえない。
>249 型コンストラクタ
251 :
250 :2006/06/16(金) 15:29:21
間違えた。 データコンストラクタだな
252 :
249 :2006/06/16(金) 15:55:07
データコンストラクタを(.)で繋ぐことってないような Data.hoge => モジュール data.hoge => 関数合成 Data hoge => データコンストラクタ でいいのでは?
普通に繋ぐよ
>>252 >データコンストラクタを(.)で繋ぐことってないような
ふつうにあると思うが。
map (Just . length) ["foo", "bar", "xzzzy"]
==> [Just 3, Just 3, Just 5]
255 :
249 :2006/06/16(金) 16:36:50
俺が無知だった<(_ _)>
256 :
デフォルトの名無しさん :2006/06/16(金) 17:11:47
高校生のムチムチの太股
関数言語のプログラムをCにコンバートすることってできないかな?
>>257 chicken はまさにそれをやってる訳だが。
C言語のプログラムをHaskellにコンバートすることってできないかな?
ドストエフスキーの小説をHaskellにコンバー(ry
プルーストの『失われた時を求めて』を遅延評価で圧縮する事って出来ないかな?
>>258 ほんとだ!
ghcのディレクトリみたら、gcc入ってた。つか、mingw
まあでも直観的にはネイティブコンパイラのほうが、 スタック等の細かい所を弄れて早そうな感じがするね。 gcc経由したほうが早くなるのは何故なんだぜ?
267 :
デフォルトの名無しさん :2006/06/17(土) 08:52:28
factorize 1000000000001 [73,137,99990001] みたいに素因数分解する関数を作り、 1== length (factorize 1000000000001) を入力すると 素因数分解するだけなのと同様な時間を要するようです。 73と137はすぐ見つかり、遅延評価により即表示されるので、 137が見つかった時点で終了して False となってくれる事を期待したのですが、わざわざ最後の素因数まで探してるようです。 lengthがリストの最後に行くまで値を返さないから ボトルネックになっているという認識で良いですか?
268 :
デフォルトの名無しさん :2006/06/17(土) 08:56:01
ハスケルさんがコンパイラ作成のプロではないからじゃね?
>>267 そうね。
p [] = False
p [x] = True
p (x:y:xs) = False
こんな感じで。
270 :
デフォルトの名無しさん :2006/06/17(土) 09:56:13
271 :
デフォルトの名無しさん :2006/06/17(土) 10:25:31
というか 素因数分解で結果のリストが一つの要素ってつまり素数の事だから p n = [n]==(factorize n) の方が適してましたね
Int値が内部でChurch numeralとかで表現されてたら
>>267 の期待通りになるかもしれないが、32or64bitで
表現されてる以上、strictに計算してみないと比較
できんわな。
大発見? ユニット型()って独立した1つの型として扱われてるけど たんなる要素数0のタプル型じゃね?
うむ 常識だったか。
276 :
デフォルトの名無しさん :2006/06/18(日) 20:37:20
Haskellで書いたプログラム(のオブジェクト)をC++でリンクしたいんだけど可能ですか? スクリプト言語で機能拡張できるソフトがあるじゃないですか、そんな感じで。
280 :
276 :2006/06/19(月) 21:10:29
ありがとう
>>277-278 これはいばらの道だ。
いきなりHaskellで0から書き直そうなんて
言えないのですよ
単にforeign exportするだけなら何も難しいことはないと思うが。
284 :
デフォルトの名無しさん :2006/06/19(月) 23:16:11
スタイルは逆であるべきじゃないの? C++で作成したモジュールをHaskellにエクスポートするって方向で Haskellで作って高速化したい細部をC/C++でとかじゃないの?
勝手に決めるな。
>Haskellで作って高速化したい細部をC/C++でとかじゃないの? 実際やろうとすると難しい 俺には絵に描いた餅のように思える
>>232-236 を見て逆に bar を先にしたいときに
((. bar) . foo . bar) って書けるんだなと思ったが
さすがにこれは (\x y -> foo (bar x) (bar y)) って
書いたほうが可読性的にいいか。
>((. bar) . foo . bar) って書けるんだなと思ったが 更に変形して ( . foo . bar ) ( . bar ) とすればfoo,barの出現順序が \ x y -> foo (bar x) (bar y) と同じになる。 もっと変形すれば ( . ( . foo)) ( . bar ) ( . bar ) と書けて、 . の数がそれぞれの引数の数に対応する。 ただ、そんな変形するよりも素直に foo (bar x) (bar y) と書いた方が可読性も良いし、リダクション数も少ない。
書籍の話。
このスレッドでは『入門Haskell』の評価があまり高くなかったけれど、
私はとてもいい本だと思った。とにかく面白かった。
もうLISPの時代じゃない、Haskellならこんなにエレガントに書けるんだ、という
主張が横溢していて、Schemeしか知らなかった私の目のウロコを吹き飛ばした。
しかし、モナドで挫折。ぜんぜん分からない。
『ふつうのHaskell』も読んでみた。『入門』よりずっとやさしく、これなら
LISPを知らなくても読めそう。しかしレイアウトルールや遅延評価、部分適用な
んかについてはずっと詳しく丁寧に説明されている。するする読めるぞ。
しかし、モナドで挫折。やはりぜんぜん分からない。
…まあ、継続やYコンビネータも、分かるのにホント、時間かかったから、モナドも諦めずに取り組むしかないか。
ということで、同じこれらの書籍の読者の皆さま、いかがお過ごしでしょうか?
何とかモナドは征服されましたか?
先達の皆さま、やはりここから先は、↓に取り組むしかないのでしょうか?
http://www.sampou.org/haskell/a-a-monads/html/
291 :
289 :2006/06/22(木) 02:58:36
>>290 ありがとう。あれは出てすぐに全部読んだ。
確かに分かりやすいけれど、今思うと、モナドの中の、IOモナドだけの説明だと思う。
つうか、説明じゃなくて比喩。
だからMaybeモナドやリストモナド、Stateモナドまでを統一的には理解できそうにない。
型 m a の構造が ・Maybe … a に値Nothingを加えた型 ・State … s -> (s, a) ・Cont … (a -> r) -> r ・List … [a] のように様々な構造をしている。これらはそれぞれ なんらかの「計算」を表すと見なせる。例えば: ・Maybe … 「失敗した」という意味のNothingを含むように拡張した型 ・State … 「前の状態」をもらって、計算結果と次の状態の対を返す計算 ・Cont … 「継続」(a ->r) をもらって、答えの型rの値を返す計算 ・List … リストのどれもが値であるような、非決定的な計算。非決定性オートマトンの状態を思い浮かべると近いか
これらを繋ぐ計算が (>>=) :: m a -> (a -> m b) -> m b の型を持つと決めたら、かなり統一的に扱える。 ここで、(>>=) は、個々の計算を「組み合わせる」演算。 第一引数の、型m a の値は何らかの 型a の値を生み出す(Contはそうでもないか)。 ここで、その値を計算の途中で「取り出して」、 第二引数の、型(a -> m b) の関数に食わせてやると、最後に型 m b の値が得られる。 という一般的な構造を持っている。 例えば、 ・Maybe … 左手がNothingなら結果もNothingとする演算。 (Just a) >>= f = f a Nothing >>= _ = Nothing ・State … 左手の計算の結果で得た「次の状態」s' を、右手の計算の「前の状態」となるように組み合わせる演算 (State c) >>= f = State $ \s -> case c s of (a, s') -> case f a of State c' -> c' s' ・Cont … 左手の継続渡し計算cの続き(多分)に、右手の継続渡し計算c'を行うように組み合わせる(そして最後に、貰った継続kを行う)演算。 (Cont c) >>= f = Cont $ \k -> c (\a -> case f a of Cont c' -> c' k) ・List … 左手のリストそれぞれの要素に、右手の計算を行わせる。リスト[[a]]が得られるので、concatで[a]に潰す。 as >>= f = concatMap f a
Listの>>=の説明、「リスト[[b]]が得られるので、concatで[b]に潰す。の間違い」 でっす。 上の説明でよくわからない所は遠慮なく聞いて欲しいっす。
mの構造に関わらず、「2つの計算を組み合わせて新しい計算を作る関数」が m a -> (a -> m b) -> m b という型で表せる、という所が美しいんです。 又、これがちょうど do 構文のような手続き的な書き方にもマッチしているのも面白い。
2つの計算を組み合わせて新しい計算を作る美しい関数 = . . :: (a->b) -> (b->c) -> (a->c)
>>289 モナドを理解するには、よく使う二・三種類のモナドに十分に(普段のコーディングで使えるくらい)
慣れるのが一番早いと思う。というわけで教科書より実践を勧める。
多くの人にとってOrdクラスが難しくないのは整数や文字列の比較に親しんでいるからであって、
全順序集合の諸性質について特に勉強したわけじゃないだろう。
この順番はHaskellを使う上での重要度にも対応する。IOモナドの使い方を知らなければ
まともなプログラムを書けるかさえ怪しいが、モナドとは何かを知らなかったところで
多少設計の幅が狭まるだけだ。
とりあえずの理解としては、
>>292 のようにm a型の値を「計算」と捉えるとか、あるいは「範囲式([1..9]とか
['a'..'z']とか)の多重定義のためにEnumクラスがあるように、do式の多重定義のためにMonadクラスがある」
というのでいいんじゃないだろうか。
いまだに Lisp, Lisp と言ってるヤツが可哀想に見えたきた。
どっちも好き
HaskellよりLispの方が最強だろ。 柔軟性においてこれに勝る言語はない。
まあな
302 :
289 :2006/06/22(木) 14:24:28
おお、ノマドについて、丁寧で親切な説明が、こんなに! 例を並べて、それらに統一的な説明をもらったせいか、今までで一番分かった 気がするよ。心から感謝します。 結局ノマドというのは、二つ以上の計算を組み合わせる時の、汎用的、統一的 な方法ということなんだろう。 いろんな計算の組み合わせを、すべてノマドという様式で統一的に扱うように したら、パワフルでエレガントで、見通しが利くようになった。その計算の内 容自体は、リストモナドみたいに簡単なものもあるし、そうでなくて難しいも のもあるけど、様式はすべて同じ。 『入門Haskell』にはいろんなモナドが載っているけれど、どうも計算内容自 体が難しくて、ついていけなかった。これからしばらくは、内容よりも様式に 注目して、様式がどのように共通しているか、共通化されてどのように嬉しい のか、一つ一つ考え直してみようと思う。 では、ありがとうございました。
ノマド?釣りなのか。
まあでもこの説明(
>>292-295 )で分かってもらえたんだったら、
これを広めればHaskellももっと認知されるな。
>様式がどのように共通しているか、共通化されてどのように嬉しいのか、 モナド変換子とか foldMとかrepeatMとかかな? あとは手当たり次第に、 Monad m => ... という型シグネチャを持ってる関数や型クラスを全部当たってみれば自ずと分かるな。
>>300 >柔軟性においてこれに勝る言語はない。
そのとおりだけど、それが何か?
Haskellは柔軟性を求めてないのでは?
まあいいんじゃないの? 静的型チェックがない言語なんて放っとけばいいじゃん。
静的型チェックがないおかげでLispのほうが優れている。
>>308 優れているというなら実例をいくつかあげてもらえるかな。
310 :
289 :2006/06/22(木) 16:02:28
×ノマド → ○モナド すげえ。書いてるときは、この間違いに全然気づいてなかった。 遊牧民が何で関係あるんだ。 あまりの低能ぶりに自分でもびっくり。
>>309 一旦数値を入れた変数に文字列入れることが簡単に出来るんだぜw
ほれ。
(setq a 1)
(setq a "string")
え?そんな副作用は汚いし避けるべきだって?
本当にそうかい?w
Lispなら2行で簡単に終わり。
既存のコードを修正することもない。
モナドのように仕様が肥大化することもないのさ。
新しい型を作るって?構造体使うって?
そんなことしなくてもLispなら2行で簡単に終わり。
既存のコードを修正することもないw
HQ9+なんかもっとすごいぜ! H これで"Hello, world!"が出るんだ。たった一文字だぜ! 短かさにおいてこれに勝る言語はない。
そうやって、型にこだわるところから柔軟性が失われ、仕様の肥大化へと 悪魔の道へ突入していく。
>>309 (replace '+ 'print func) ;;funcの中の+演算をprint関数に変える
みたいなことができてしまう。
funcのソースコードを動的にいじっているのも凄いし、
+とprintなんて引数の型とか全然違うのに置き換えられるのも凄い。
柔軟性柔軟性って、Lisperは酢かソフランでも飲んでろ。
>>315 「凄い」を「危ない」に置き換えて読めと言っているようにしか見えない。
>>311 >モナドのように仕様が肥大化
モナド知ってて書いてるのかこいつ。。。加えてSICPにも載ってるside effect bugをもう一度読み直してみれ。
簡単なのは良いことだし,emacsのような動的に拡張できたほうが気持ちが良い環境というのもあるけれど,
型が無いことは最早モダンなプログラミング言語のメリットに数えることは難しい。
>>311 はどうやら知識が足りないみたいだから、議論にはならないな。
Haskellでプログラムを書けば,型のおかげでランタイムエラーがないことを (ほぼ) 保証できる。 特に純粋関数型部分なら,パターンマッチの漏れが無ければ,ランタイムエラーが「起こらない」。 (メモリのオーバーフローや,再帰が止まらない可能性はある) Lispにそれができるのかな?
322 :
321 :2006/06/22(木) 18:15:18
あ,0除算とかも防げないか。当たり前だけど。
柔軟であることは強力だが、それは諸刃の剣であり
人間が間違いを犯す余地を増やす。
Lisp は確かに柔軟であるが、使いこなすには
間違いを犯さない注意深く優秀な人間でなければいけない。
そのようなものにとっては Lisp は Haskell より優れているだろう。
しかし煽りだか釣りだかネタだかよくわからない
>>311 のようなバカには
Lisp は奨められない。Haskell にしとけ。
テスト駆動開発隆盛の現在、その危なさも問題じゃないということが わかってきてるんだよ。 時代が進むにつれてLispが有利になる。まだ時代はLispに追いついていないんだよ。
lisperも流石にC++やJavaをコキおろす時のようにはいかないと思う。 >時代が進むにつれてLispが有利になる。 ガベコレや継続がまだ余り知られていなかった時代じゃあるまいし。 Lispに型システムさえあればねえ。。。 機械によるプログラムの安全性の保証が必要になる分野はこれから沢山出てくると思われる。 そんな所にLispが使われていたら俺は嫌だ。せめてJavaにしてくれ。 テストではバグがないことは示せないが、型ならある種のバグの不在が証明できる。
まあそのうちわかるよ。機械による安全性の保証をするにも型が邪魔だってことがね。 時代が証明するだろうw
>>324 > テスト駆動開発隆盛の現在、その危なさも問題じゃない
いやそれは危ないのが現実になってしまっても、
バグ頑張って取るから大丈夫ですって言ってるだけだろ。
バグ頑張って取らなきゃいけない時点で負けなんだよ。
>機械による安全性の保証をするにも型が邪魔だ 完 全 に 誤 解 で す 。
誤解というより無知なんだろうな
もうやめようよ。 基礎知識がないみたいだから、説明するにも基礎から説明しないといけなくなる。
なんか便乗されてるw あんまり無知無知言ってやるなw
わかるよ。 Haskellは数学を使っているし、最新の研究を盛り込んだ学術的な言語、 だからHaskellは凄いに違いない、マンセー! そういう奴もあらわれるわな。 そういう雰囲気を持った言語だよ。Haskellってのは。 だから、Fortoranの次ぐらいに古いLispなんかに劣ってるとは信じられない、 相手が無知なんだ!そう思う気持もね。 その先入観はわかるw
Hoare理論も計算モデルも意味論も型が入ったとたんに難しくなるw 型のせいで理論が肥大化するんだよ。
336 :
デフォルトの名無しさん :2006/06/22(木) 18:55:09
と言うか、ネタキャラを演じて、玄人ばかりだったらやらないような、 初心者向けのテーマの議論を盛り上げようとしてくれているんだろうけれど、 ちょっとうまくかみ合わなくて、痛々しい感じがして、そこがつらいよな。
>>336 普通にLisp信者ですが何か?w
Lispに劣ってるHaskellなんかが威張ってるのが気に食わなくてね。
マイナーなほうが幸せな面もあるよ。
個人的には、ここでlisplisp言ってる人にぜひ、Haskellじゃなくていいから、OCamlとかCleanをやると良いと思う。 単に雰囲気だけじゃなく、利点があるわけで。 触りもせずに批判するのは怠慢。 全ての言語はLispに収束すると無批判に信じるのは無能。 というか、言語のどれが最強というのがそもそも意味がないんだけど。 >だから、Fortoranの次ぐらいに古いLispなんかに劣ってるとは信じられない、 ええ、Haskell にも、LispどころかJavascriptにさえ劣っている部分がありますよ。型があるってことです。 もちろん、Lispより優れている部分もあります。型があることと、遅延評価がある事です。
ん,Lispに遅延評価ってないんだっけ。マクロがあるからcall-by-nameはできるか。
341 :
デフォルトの名無しさん :2006/06/22(木) 19:21:20
lisp信者じゃないけどその程度の認識でlispを批判するのもどうかと
Lisperだからってevalなよ。
Haskell屋の気に入らないところは、さんざん型を崇め奉る癖に、 自分のコードには型宣言をほとんど書かないこと。 型が仕様だというなら、推論させずに自分でちゃんと書け! そうすればSystem F並の記述力も得られるだろが
いやむしろLisperだからevalしか能がない。
345 :
デフォルトの名無しさん :2006/06/22(木) 19:39:30
遅延評価はHaskellのはるか前からLispで実現してた
>>340 マクロとは別に、delay-forceって構文があるんだけど、とにかく煩雑になりがち。
何から何まで手動でやらなきゃならない。
Haskellの遅延評価、グラフ簡約を知ったときには、LISPがHaskellの30年前に
生まれた言語だということを痛感した。
347 :
デフォルトの名無しさん :2006/06/22(木) 20:24:10
たかがdelay-forceで大げさな。 OCamlだってそうじゃねえか。 大抵はlambdaやマクロでこと足りるしな。
形無し言語逝ってよし
何も考えず定義を書き下せば、それなりに効率よく実行されるのは、一度味わうと結構オイシイよ。 ビバ遅延評価。まあ遅延評価じゃない方が良かったという意見はどっか上の方でもあったけど、 何度も言われているけど様は「向き不向き」でそ。 もちろん効率ばかり気にするCモンキーな人々には遅延評価はオススメできない。
議論に便乗して論点に関係ない意見を垂れ流すのはやめれw
>>325 > そんな所にLispが使われていたら俺は嫌だ。せめてJavaにしてくれ。
Javaの型は明らかに崩壊しているので、アレなら無い方が記述力が上がって
便利なのではないかという気がするぞ…
別に論点ずれてないし。HaskellよりもLispのほうが優れている、とかいう厨なおじさんが居るから 遅延評価のお陰でスッキリ書けるHaskellもいいぞ、と言ってるんだけど。それも釣りなのか。
>>343 は、それはそれで気になる。
というかどうでもいいLisperよりもずっと気になる。
System F並の記述力って何? よく知らないので詳細きぼん。
System Fが多相型のシステムだというのは調べれば分かるんだけど。どれくらいリッチなのか。
>>339 >ええ、Haskell にも、LispどころかJavascriptにさえ劣っている部分がありますよ。
お前、Javascriptをなめんなよ?
javascriptが優れてるのはよーく分かってるから。
Lisp>JavaScript>Haskell Haskell厨は身の程をわきまえろよ。
VBはどこに入りますか?
Lisp>JavaScript>VB=Haskell この辺。
Haskellって大規模なデータをちょっとづつ変更しようとしたら、丸ごと変更しなくちゃいけない ところがどうしようもなく糞。
361 :
デフォルトの名無しさん :2006/06/22(木) 21:37:41
豊富なライブラリと簡単な開発環境、日本語ドキュメントがそろうと Haskellの開発効率最強でしょうか。
Lispが最強。
>>361 Haskellは開発環境を作るという点ではあまり向いていないかも。
便利な開発環境というのは、リアルタイムでソースを解析する必要があるけど、
ああいう複雑な構文は解析するのも一苦労じゃないかな。
JavaやC#の方が向いている。
Lispも向いているんだけど、最近誰も使ってないから、emacs以外は進化した環境が
あんまりないね。
Haskellの構文は複雑か? Haddockはパーザを持ってるわけだし,パッケージLanguage.Haskellとかも使えんかな。 とりあえずVisual Haskellとeclipsefpに期待。 Lispの開発環境にはアレグロ何とかがあるけど、この話をすると何とかさんが湧いてくるのでやめとく。
まあ、Haskellを使いたいと思ってない人にわざわざ説明してやる気もないんだけど。。。
二つともeclipseJDTに比べたらウンコだね。
どうでもいいけど日本語扱いたいよ。 文字コード変換ライブラリとかどっかに転がってないかな。
>>366 あれは全言語含めた全開発環境中でトップクラスと言っても過言ではないでしょ。
NetBeansでJavaもいいけど。
開発環境ではJavaや.NETが一歩も二歩もリードしてる。
>>367 haskellerなら英語で書きなよ。
javaが優れてるわけじゃなくてユーザーが多いからだけどね。
>>368 また年季の入ったLisperやSmalltalkerに喧嘩売るような発言を…
どっちも型ないし、このスレのスタンス的には喧嘩売る方向で。
静的型付けがあった方がいいとか、何十年も前から言われ続けてるのに 結局静的型付けがない言語が生き延びてる。 それどころか、AjaxやPythonなどのブームで勢いを取り戻し始めている。
20年後、HaskellとLispのどちらが生き延びているかといったら、 Lispだろうなw
その分優れたな静的型付けの言語が現れていることでしょう。 ずっと変わらないのはLispだけ。
Ajaxがブームなのは、ブラウザ周りの文字列からの型変換(シリアライズ/デシリアライズ)に関して明確な仕様も実装もないため。 また、HTTPが文字列ベースのプロトコルだから。 つまりIEその他のブラウザがクソで、wwwサーバやその仕様にも進歩がないから。 IEがユーザからの入力を型の付いた形で扱えていれば、それを操作するスクリプト言語も静的型付けのものを用いるのが妥当になる。 wwwサーバがCGIを呼び出す時点で型が付いた値を渡していれば、それを扱うwebアプリも静的型が付いた型安全な言語で良くなる。 全部レガシーのせい。もしくはwebの研究者とプログラミング言語の研究者がサボっているせい。 ...等と言ってみる。
なんでも人のせいにするな、と親に言われなかったか?
>>375 Lispは時代のはるか先を行く言語だからな。
どこぞの言語がLispのガーベッジコレクションや遅延評価などを真似したりして
ちょっとずつ時代が追いついてきてるけどなw
それこそ数十年後には、The 型付き言語 みたいなのが現れてるかもしれんな。 それぞれのプロトコルやwebサーバ、OS等も型付き言語を意識した設計がなされる。 なぜLisperがこうした未来を想像できないのか不思議だ。 ガベコレやクロージャが現在の言語でやっと使われているのと同じで、 C#やJavaにも型推論が入る時代が既にそこまで来ているわけで。
数十年後には静的型付きという概念は劣勢に追い込まれてるだろうからな。
ガベコレが馬鹿にされていた時代があった。 効率は悪いし、そもそもmallocを呼んでfreeを呼ばない馬鹿は居ないと皆が思っていたからだ。 でも今ではガベコレ無しの言語なんて考えられない。 同じように、型や型推論がこの先重要な位置を占める世界を欠片も想像できないとは、おまえら本当にLisperなのか。
>>381 答えはこういうことだよ。
静的型付けは*現在*重要な位置を占めている。
現在は動的型付けが馬鹿にされている時代だ。
効率は悪いし、危険だとみなが思っているからだ。
でもそのうち静的型付けの言語なんて考えられなくなる。
何度も言われているが、無批判無根拠にLispが至上であると妄信するやつはカス。 もちろんそうじゃないlisperの方が多数派だろうが。
>>381 もあるかもしれんな。それが答えだとは全く思わんが。
Javaを見ろよ。静的静的なんていってたのは最初だけ。 現在はクラスを動的にロードしまくり、Springとかリフレクションバリバリ使って どこが静的なんだよって感じだ。 今でも兆候は現れてるよ。
それwebだけでそ
Haskellの話題に戻ってください
>現在は動的型付けが馬鹿にされている時代だ。 >効率は悪いし、危険だとみなが思っているからだ。 危険なものと自分で言っているのに、それを今後みんなで使うようになると妄想できる根拠は何だ?
動的とかwebとかどうでもいいよ
「そんなのはlispのやることでしょ」
入門HaskellとふつうのHaskellって両方読んだほうが良い?
動的型付け言語は、短いプログラムを書くのに適している。 まさに「スクリプト言語」はこれに相当して、 こういうのは逆に静的型付けだと鬱陶しい。 逆に、静的型付け言語は、長いプログラムを書くのに適している。 動的型付け言語で起こるだろう多くのバグを、 コンパイル時に排除できるからだ。 「素晴らしい言語」なんてのは、適用対象が違えば変わっていいわけで、 あるただ一つの言語だけが素晴らしいとか言ってんのは見てらんない。
型が無いとfromEnumとかreturnみたいなのが書けなくね?
toEnumだた。
LispにしろSmalltalkにしろSelfにしろRubyにしろ、間違いなく タイプセーフなわけで、こいつらを捕まえて型がないと言うのは 大間違いだぞ。CやC++に比べると、はるかにしっかりと型付け されている。
ヒント:静的型と動的型
>あるただ一つの言語だけが素晴らしいとか言ってんのは見てらんない。 ここに張り付いてる動的型付け言語の信奉者がまさにそれなんだが。
だからこのスレでHaskell以外の話題を引っ張るなと
Haskellも短いプログラムを書くのに適している気がするんだが。 簡潔な構文と高階関数のおかげで幾らでも短く書ける。 おまけに型安全だから安心。 スクリプト言語のプログラムも関数型の機能を取り入れて、更に簡潔になる傾向にあるが、 これらには静的型付けもないし型推論もない。 短いプログラムを、何も考えずにさっと書けるのがスクリプト言語。 短いプログラムも、熟練すれば型安全にさっと書けるのが関数型言語。 確かに学習コストは少し高め。
402 :
401 :2006/06/23(金) 06:23:40
あ、スクリプト言語じゃなくて動的型付け言語か。
>>401 動的型言語が熟練を必要とせず、静的型言語が必要とする理由はあるのか?
ただ、慣れの問題では?
熟練≒慣れ ただ(静的型付けの)関数型言語が動的型付けの言語より学習コストが高い、というのは当たってると思う。 そうじゃなかったらもっとOCamlやHaskellの利用者が増えているだろう。 世の中、動的言語で提供される柔軟性が必要な分野ばかりではないから。 ただ、今流行ってるようなwebプログラミングにはいわゆる「柔軟性」が必要な部分があるのかもしれない。
>>393 入門Haskellのほうは読まなくてよい。あれは・・特殊です。
ふつうは2日で通読できた。 入門はさめがめの章でつまづいて、しばらく放置。 ただ、どちらも読みやすいよ。 その前に Craft of なんたらを読み始めてたけど、 数学の知識のない俺には例題の敷居が高すぎた。
分からないのはノマドらしいが…
409 :
デフォルトの名無しさん :2006/06/23(金) 19:06:06
Lispは関数型言語界のC/C++ですね
410 :
デフォルトの名無しさん :2006/06/23(金) 20:28:54
関数型言語の本とかサイトって数学の例ばっかりなのが萎えるんだよね。 お前らそんなに素数とフィボナッチ数列が好きかと。
まあ好きだけどな
そんな事言っても好きなんだからしょうがないだろ!
「ふつう」読了。深みはなかったような気がするけど、Haskellの概要が わかったのがよかった。 monadと(オブジェクト指向の)メッセージチェーンと似ているのは意外で面白いな。
継続とかアクターとか同じ穴の狢だぜ。
416 :
デフォルトの名無しさん :2006/06/24(土) 02:07:33
Visual Haskell インストールしようとしたら最後にエラー出てキャンセルされる… 俺のPCが98だからか?
417 :
デフォルトの名無しさん :2006/06/24(土) 02:08:47
ghciで走らせるのって遅い?
418 :
デフォルトの名無しさん :2006/06/24(土) 18:10:36
すみませんが、質問です。
『入門Haskell』のP135なのですが、
[x | x <- [1..10], x `mod` 2 /= 0]
が
do {x <- [1..10]; guard(x `mod` 2 /= 0); return x}
と同等であるという説明があります。
ここの x <- [1..10]という演算が何をするのか、よく分かりません。
x <- [1] なら分かるのですが、複数の要素に何をしているのでしょう?
結果的には、[1..10]のすべての要素に guard 以下が実行され、その結果が
mplus である ++ で結合されています。
しかし、式の中には mplus も出てこないので、なぜmplusが呼ばれるのかも
分かりません。
↓も見てみましたが、
http://www.sampou.org/haskell/a-a-monads/html/listmonad.html <- 演算子が何をするのか、mplusとどう関係するのか、結局分かりません
でした。
420 :
418 :2006/06/24(土) 18:46:15
>>419 すみません、私はモナドを理解できていないのです。
質問が分かりにくいのかも知れませんので、補足します。
<- は return の逆演算に似ていて、リストモナドなら[a] を a に
戻す働きがあります。
x <- [1]なら、[1]を1に戻し、x を 1 に束縛するのだと思いますが、
x <- [1..10]だと、xに何が起こるのでしょう?
まさか1〜10が同時に束縛されるはずはないし。
>>が多すぎると言われたので全角で失礼。 do { v0 <- e0; v1 <- e1; ...; eN } は e0 >>= (\v0 -> e1 >>= (\v1 -> ... eN)) の略記。このことと、 x >>= f = concatMap f x return x = [x] guard b = if b then return () else mzero mzero = [] を踏まえると、次のように変形できる。 do {x <- [1..10]; _ <- guard(x `mod` 2 /= 0); return x} = [1..10] >>= \x -> guard(x `mod` 2 /= 0) >>= \_ -> return x = [1..10] >>= \x -> (if x `mod` 2 /= 0 then [()] else []) >> \_ -> return x = [1..10] >>= \x -> (if x `mod` 2 /= 0 then [()] else []) >> \_ -> [x] = [1..10] >>= \x -> concatMap (\_ -> [x]) (if x `mod` 2 /= 0 then [()] else [] = [1..10] >>= \x -> if x `mod` 2 /= 0 then [x] else [] = concatMap (\x -> if x `mod` 2 /= 0 then [x] else []) [1..10] 見ての通り、mplusは無関係。
>>420 >x <- [1..10]だと、xに何が起こるのでしょう?
直感的には、次のような感じ。
・まずx=1として後続の計算が行い、この結果をv1とする。この例ではv1 = [1]
・次にx=2として後続の計算を行い、この結果をv2とする。この例ではv2 = []
・以下同様にv3..v10を計算し、すべてを++で結合する。
この操作はconcatMapに他ならない。厳密な定義は
>>421 参照。
423 :
418 :2006/06/24(土) 19:07:11
うわっ、難しい。 ありがとうございます。ちょっと考えてみます。
424 :
421 :2006/06/24(土) 19:14:55
>= [1..10] >>= \x -> (if x `mod` 2 /= 0 then [()] else []) >> \_ -> return x >= [1..10] >>= \x -> (if x `mod` 2 /= 0 then [()] else []) >> \_ -> [x] >= [1..10] >>= \x -> concatMap (\_ -> [x]) (if x `mod` 2 /= 0 then [()] else [] この三行は間違ってた。こっちが正解。 >= [1..10] >>= \x -> (if x `mod` 2 /= 0 then [()] else []) >>= \_ -> return x >= [1..10] >>= \x -> (if x `mod` 2 /= 0 then [()] else []) >>= \_ -> [x] >= [1..10] >>= \x -> concatMap (\_ -> [x]) (if x `mod` 2 /= 0 then [()] else []) 二回>>=を>>と書いていたのと、括弧の閉じ忘れ。 混乱させてすまん。
別人ですが、似たような疑問を持っていたので面白く読めました。 Listの >>= は concat . map なのですね。 do ... = ... >>= ... >>= ... >>= ここは納得できたのですが、 > [1..10] >>= \x -> concatMap (\_ -> [x]) (if mod x 2 /= 0 then [()] else []) > [1..10] >>= \x -> if mod x 2 /= 0 then [x] else [] この置き換えが分かりません。 m >>= (\x -> mzero) == mzero 規則にあるこれだとは思うのですが・・ ユニット型がなにか特別な意味を持つのですか?
427 :
426 :2006/06/24(土) 22:25:11
書いて気づいた。 (return x) >>= f == f x こっちの方ですね。 >>=がmapなんだから、[]を吐けば以後の計算を殺して[]が返せるのか。
>>425 動かしてないけど、少なくともHaskellのコールバックを呼ぶ可能性のある関数はunsafeで呼んじゃいけないと思う。
IupMainLoopへのcallフックのunsafeを外したら動いた。
430 :
425 :2006/06/25(日) 08:45:27
>>428-429 ありがとうございます。確かにunsafeを外したら動きました。
きちんと理解せずにunsafeを付けていました。
単に副作用のある関数を呼ぶときにunsafeを付けるのだと思ってました。
431 :
デフォルトの名無しさん :2006/06/25(日) 16:27:15
ghcでコンパイルしたバイナリってDLLとかに依存せず動く?
動きません
433 :
デフォルトの名無しさん :2006/06/25(日) 21:48:57
配布時に何がいるの?
恐怖と絶望
windows以外だとlibgmpに依存。 これ以外ではシステムの標準的なdllにしか依存しないと思う。
436 :
425 :2006/06/26(月) 13:35:36
IUPが一応動くようになったんでIUPのラッパー部分だけ切り分けてライブラリにしてしまおうと思ったのですが、 ghc -cで生成された.oファイルたちをarでまとめて IUPの必要なライブラリとともにld -r -whole-archiveでghci用の.oファイルを作ったのですが、 ghciで実行しようとするとunknown symbol `_CoInitializeEx'が出てしまい動かせませんでした。 なので、前回実行ファイルを作るときにリンクしてたole32とかのライブラリを追加してみたら 今度はUnknown PEi386 section name `.idata$4'となって駄目でした。 どうしたらいいんでしょう?
入門Haskellの最後の最後の練習問題(Base64のデコード)だけがどうしても解けません。 mixi内で色々教えてもらったのですが。ぶっちゃけ何がわからんかすらわからなくなってしまいました。 もう諦めモードで検索する気も起きないです。 答え教えてください。
438 :
437 :2006/06/26(月) 15:50:24
ごめん。ありえないことに書いたとたんメール来て答えわかった。 すまそ。
あっそ
ココに書けとは言わないから 答えをどッかに見えるところに 還元すれ
型構築子でメモリがないときは例外があがりますか?
>>443 GHCだとメモリ不足は問答無用で強制終了。
ところで、「型構築子でメモリがないとき」ってなんだ?
データ構築子の間違いか?
>>444 メモリ不足が勝手に死んでたら、Haskell ではまともなアプリは書けないな。
致命的な言語設計だな。
WindowsやLinuxでしか使わんなら、おかしな処理をしていない限りメモリ不足にはならないんじゃね?
言語設計の問題ではありません :)
JavaではきちんとOutOfMemoryが言語仕様として定義されてるけどね。
そもそもそんな実用バリバリの言語と比較されてもね。
要は言語設計者の好みだな
VMごと丸々扱えるJavaと一緒にされてもね。
Javaにトラウマがある奴が少なくないなw そんなレベルの奴らじゃあこれも上達せずに放り投げるのだろうな。
Javaは初心者用の言語なのに・・・何言ってんだろ。ドカタ仕事多いし。
>>452 JavaではきちんとOutOfMemoryが言語仕様として定義されてるけどね。
そもそもそんな実用バリバリの言語と比較されてもね。
要は言語設計者の好みだな
VMごと丸々扱えるJavaと一緒にされてもね。
各種実装の問題だな
Javaにトラウマがある奴が少なくないなw そんなレベルの奴らじゃあこれも上達せずに放り投げるのだろうな。
Javaは初心者用の言語なのに・・・何言ってんだろ。ドカタ仕事多いし。
>>459 JavaではきちんとOutOfMemoryが言語仕様として定義されてるけどね。
>>445 じゃあ、getLine なんか使ってるプログラムに長い行を入力すると落ちるのか。
実験してみようとしたけど、落ちる前にスラッシングでハードディスクが
心配になり小心ゆえに実験を継続できない。
なにはともあれ、しぶといことは分かった。
こちとら慈善事業で、とか言われた
はすケロだた。 jpgのうしろに .htmlをつけて ダウンロード をクリックすれ。
>>468 萌フォルダとgagフォルダのどっちに入れるか正直悩んだぞ
lVV,- 、 , - 、 l ( ● 'ー' ● ) ! / -―- 、 ヽ | l '⌒l l⌒' .l ヘ 〃, { ̄} ,〃 /  ̄ ̄ ヽ
>>470 馬鹿野郎!
すれ違いもいい加減にしやがれ
#でもnukoフォルダに入れた。うきゃー
>>471 うは。
さすが2ch
AAになるとは思わなかった
474 :
425 :2006/07/03(月) 12:36:15
またコールバック関連で問題が発生しました。 Cのヘッダではコールバック関数の型は typedef struct Ihandle_ Ihandle; typedef int (*Icallback)(Ihandle*); と定義されているので FunPtr (Ptr () -> IO CInt) のような型に読み替えられるわけですが、 実際に登録されるコールバック関数はIhandle*以外にも引数を取るようなものだらけだったりします。 この場合、コールバック関数の型ごとにラッパーを用意してやるしかないのでしょうか?
475 :
425 :2006/07/03(月) 14:51:05
よく考えたらString<->CStringの変換とかもあったりするから個別に書いてやらないと駄目ですね。orz
476 :
デフォルトの名無しさん :2006/07/06(木) 13:20:03
すみませんが、素人くさい質問です。 クロージャはなぜ重要なのでしょうか? この前、知人と部分適用とカリー化について話をしていて、 add x y = x + y という関数があるとして、 add2 = add 2 と書けば簡単に x=2と束縛したクロージャが得られるんだ、と 説明したところ、知人に、 function add2(y) { return add(2, y); } で良いんじゃない?何でそんな仕組みが必要なの?と言われました。 絶句しましたが、自分は理由を説明できなかったのです。考えてみたら、 Haskellは再代入ができませんから、クロージャが保持している変数を変更す ることはできない。良くあるような、呼び出すたびに値をインクリメントする カウンタなどのクロージャは書けないのです。こうしてみると、上のHaskell のadd2と下のJavaScriptのadd2()の違いは、関数呼び出しが一段余計に行われ ていることだけのような気がします。 こういう場合、クロージャであることには重要性はないのでしょうか?もし重 要性があるならその理由を、重要性がないなら、どういう場合にクロージャが 重要なのか、さわりだけでもお教えいただけたら幸いです。
>>476 その場合は2が定数だからadd2をクロージャ無しで書けるけど、
実行時に決まる値を使いたい場合はそうはいかない。
478 :
476 :2006/07/06(木) 14:48:14
>>477 ありがとうございます。
何か学術的な答えを予想していたので、ちょっとびっくりしました。
例えば、クロージャがないとYコンビネータが書けない、とか、言語仕様で
○○を実現するために必要、とか。
すると、値が実行時に決まる場合のみ、クロージャには意味があるのでしょうか?
定義時に決まる場合、クロージャである必要はないのでしょうか?
479 :
デフォルトの名無しさん :2006/07/06(木) 18:33:13
そもそもJavaScriptってクロージャないの? ありそうな気がするが……。
Javascriptにはクロージャあるよ。
>>476 俺もそれの必要性が理解出来てない一人。
add2 y = add 2 y
で良い気がする。
しかも
div x y = x / y
half x = div x 2
と同じことが出来ないと思うし。
>>482 なんとなく分かったような。
その場合、yを束縛した関数が帰ってくる?
逆にxだけ縛る方法ってあるの?
>>481 >>476 が問うているのはクロージャの必要性。
お前が言っているのはカリー化の必要性。
カリー化はクロージャと違って無くてもそれほど記述力が失われる訳じゃないだろ。
Haskellにカリー化があるのは、便利なのと、型システムや文法が単純化されるからだと思う。
485 :
484 :2006/07/06(木) 19:54:25
ごめん、読み違えた。 忘れてくれ。
>>483 違う。xだけ束縛している。
例えば、リストの全ての要素にnを加算するなら、
addAll n list = map (add n) list
と書ける。このとき、addの第一引数はnに固定されている。
yだけ束縛したいなら、
add_y x = add x y
または、無名関数を使って
\x -> add x y
で良い。
逆じゃないか?
489 :
487 :2006/07/07(金) 06:29:39
>>476 「重要」って言葉を選んでいるのはどうしてなの?
「何でそんな仕組みが必要なの?」への答えは、
「〜は重要である」でなければいけないの?
実は
>>476 の文章とは裏腹に、
「絶対に必要な理由」を求めようとしている気がする。
>>478 にそれが透けて見える。
491 :
486 :2006/07/07(金) 11:36:07
add_y xとか引数の名前変えても無駄だった。 方法は見つけたけど、引数の順番を変えたdiviRを定義しないような、 もっとシンプルな書き方無いかな? divi x y = x / y -- half = x / 2 と同等 half = diviR 2 where diviR y x = divi x y -- "3.5"を出力 main = putStr (show (half 7))
492 :
486 :2006/07/07(金) 11:38:45
↑の場合、halfはyを2で束縛したdiviと言って良い?
>>491 まず、何をしたいのかはっきりさせてくれ。
単に二で割る関数を書きたいなら、
half x = divi x 2
で良いし、2に限らず一般のmで割りたいなら
divm m = f
where
f x = divi x m
とすれば良い(カリー化を使えばもっと簡単になる)。
部分適用だけを使ってhalfを定義したいというなら、それは無理。
おまえら発言を省略しすぎ。 もっとくどく書け。
496 :
486 :2006/07/07(金) 12:40:57
いや、
>>481-487 の流れがあるから、
わざわざ言わなくても良いと思ったんだけど。
別に割る関数が欲しいんじゃなくて、
途中又は最後の引数に対してカリー化したいという話。
diviが複雑な関数だったら、ということ。
で、無理ですか。ちょっと残念だけどサンクス。
ごめんなさい、例が悪かった。あれじゃ half x = divi x 2 で良くなる。 divi x y = x / y --このdiviYをよりシンプルに定義する方法 diviY y = f y where f y x = divi x y half = diviY 2 main = putStr (show (half 7))
498 :
476 :2006/07/07(金) 12:56:29
>>490 > 実は
>>476 の文章とは裏腹に、
> 「絶対に必要な理由」を求めようとしている気がする。
うわあ、大正解です。
例えば、モナドもクロージャで実装されていると聞いたことがありまして(う
ろ覚え)、クロージャがHaskellにとって本質的に必要なのではないかと予想
していたのです。
>>476 は、それを考えるきっかけではありましたが、本当に知りたいこととは
少しずれています。
499 :
486 :2006/07/07(金) 13:05:58
余計おかしくなってしまったのでorz
>>487 の例で書きます。
--こんな感じで書きたい。n(割る数)を固定する
diviAll n list = map (divi ? n) list
>>499 そのままでは無理だけど、
diviAll n list = map (flip divi n) list
とか、
diviAll n list = map (`divi` n) list
とか、
diviAll n list = map (\x -> divi x n) list
などと書ける。どれも単純な部分適用ほど読みやすくないけど。
diviがもっとたくさんの引数を取る複雑な関数だったら、
diviAll n list = map divN list
where
divN x = divi x n
というスタイルが書きやすいかな。
>>500 > diviAll n list = map (`divi` n) list
今回はdivi = (/)なわけだから、
diviAll n list = map (/ n) list
でOK。
実際、(/ 2) 4 = 2.0だし。
502 :
486 :2006/07/07(金) 13:46:05
そういえば演算子も2引数の関数なんでしたね。 こういう使い方は知らなかったんで、勉強になった。 -- v = 10 `divi` 2 -- v = (`divi` 2) 10 -- v = (/) 2 10 -- v = (10/) 2 v = (/2) 10 main = putStr(show v) > diviAll n list = map (`divi` n) list 2引数の場合は、これが一番スマートですね
>>502 3番目だけ違ってる。
(/) 2 10 = 2 / 10
504 :
デフォルトの名無しさん :2006/07/09(日) 23:49:13
なにもしないmainを書くいちばん簡潔な方法はどんなものでしょうか? 空文字列をputStrなどはナシで。
506 :
504 :2006/07/10(月) 00:03:24
>>505 できました。ありがとうございます。
ところで、main = IO () では駄目なんでしょうか?
Not in scope: data constructor `IO' だそうです。
IOは型構築子であって、データ構築子ではないからね。
508 :
504 :2006/07/10(月) 01:04:53
ありがとうございます >507 IO型のデータ構築子について知るには、どこを見ればよいでしょう??
せめてテンプレのサイトぐらい読んでから質問しろと
>>508 IO aは抽象型であって、データ構築子は公開されていない。
代わりにデータ構築用の関数(return, (>>=), putChar, putStr, ...)が
公開されているから、それを使う。
511 :
504 :2006/07/10(月) 06:37:28
ありがとうございます >510 IO型のデータ構築用の関数について知るには、どこを見ればよいでしょう??
>IO型のデータ構築用の関数について知るには、どこを見ればよいでしょう?? 一覧が欲しいってこと?IO動作を返す関数なんていくらでも書けるし、 Cの関数を自由にforeign importできるから完全な一覧はありえないけど、 Haskell98の範囲なら、Prelude, Monad, IO, Directory, Systemあたりのライブラリを 調べればいいんじゃないだろうか。 これらのライブラリの仕様はHaskell Reportに載ってる。
>512は世界一優しい男
514 :
デフォルトの名無しさん :2006/07/10(月) 08:18:48
べ、別にあんたのためにレスしたんじゃないんですからねっ!
515 :
あかさ :2006/07/10(月) 08:55:59
cかぁ. . .
可変個の引数ってとれないの? ということはprintf的なものも無理?
リストを取ったら?
518 :
517 :2006/07/13(木) 15:19:05
あ、それだと同じ型の値しか取れないか。 脊椎反射レススマソ。
>>516 基本的には無理。ただし型クラスを駆使して実現できる場合もある。(Text.Printf参照)
他にも、Template Haskellでコンパイル時にフォーマット引数を解釈したり、
C++みたいに二項演算子で妥協することもできる。
521 :
デフォルトの名無しさん :2006/07/14(金) 04:51:14
本家メーリングリストにときどきoleg氏が投下しているような 型クラスのコードを読めるようになりたいんだけど、このあたりの挙動について 参考になる文書か何かweb上にある?
ghcで add = (+) の型が Integer -> Integer -> Integer となるのですが、 (+)の型が、 (Num a) => a -> a -> a なのにどうしてでしょうか。
なお、コマンドラインオプション -fno-monomorphism-restriction を付けるか η展開形 add x y = (+) x y で定義すると add :: (Num a) => a -> a -> a になるよ。
525 :
516 :2006/07/14(金) 21:07:10
527 :
デフォルトの名無しさん :2006/07/17(月) 05:27:30
オフサイドラインw
一気に寂れたなw 本が発売された前後だけかw
529 :
デフォルトの名無しさん :2006/07/20(木) 10:07:46
すみませんが、質問です。タプルの使い方が良く分かりません。 タプルは、LISPの多値に対応するものだと思うのですが、ある関数の戻り値が タプルの場合、それを受け取れる関数は、引数がタプルである必要があります (よね?)。多引数の関数に汎用的に与えることはできません。2つ組みのタ プルの場合だけは、curryとuncurryがありますが。 ということで、多値の代用としてのタプルの使い方の定石のようなものがあっ たら、教えていただきたいのです。 ちなみにPythonにもタプルがありますが、こちらは、関数に複数の引数を与え る代わりに、タプルを与えることができます。* という演算子があって、 a = (1, 2, 3) (lambda x y z: x + y + z)(*a) => 6 という書き方ができます。 再代入のできる手続き型言語とは、だいぶ事情は違うのでしょうが。
530 :
529 :2006/07/20(木) 10:09:55
訂正 (lambda x, y, z: x + y + z)(*a) => 6 引数のカンマが抜けていました。まあPythonの話ですが。
タプルはリストやLispのconsセルとは全く違うものです。 任意のnに対してn-タプルを受け取る関数、といったものは定義できません。 どうしてもそういうのが欲しいのならTemplateで「n-タプルのi番目の要素を取ってくる」 みたいなのをコンパイル時に生成するとか、タプルでなくともHeterogeneousなリストが 使いたいだけならType Classを駆使するとか、方法はなくはない。 ときに、実装内部はともかく、Haskellに「多引数の関数」は存在しないので誤解なきよう。
532 :
529 :2006/07/20(木) 14:16:32
>>532 >ちょっと考えたのですが、ある組み合わせのタプルを返す関数を書くなら、
>同じ組み合わせのタプルを受け取る関数も書くのが普通、という理解でよいでしょうか?
受け取る関数がないならタプルを返す関数はそもそも必要とされないと思う。
もし受け取る関数がないのに必要とされるならばそれは副作用がメインで、
おまけでタプルが返ってくるような場合なんではなかろうか。
>>529 タプルがそれ自身で意味を持つ場合、引数もタプルで取ることがある。例えば、
Data.Ix.range :: (Ix a) => (a, a) -> [a]
Data.Ix.index :: (Ix a) => (a, a) -> a -> Int
この場合(a, a)で「範囲」を意味している。
一方、単に複数の戻り値を返したいというだけの場合は、
いちいちパターンマッチで取り出すのが普通だと思う。
let (a, b, c) = f x in g a b c
この使いわけがあるから、カリー化された関数にタプルをそのまま渡せなくてもそれほど困らない。
もちろん、不便な場合もたしかにあると思うが。
不便だと思えば、uncurry3, uncurry4, ...を定義するとか、
型クラスとGHC拡張を使ってこれら全部に同じ名前を与えるとか、
Template Haskellで一般化して$(uncurry 4)みたいに書けるようにするなどすれば良いと思う。
>再代入のできる手続き型言語とは、だいぶ事情は違うのでしょうが。
どちらかというと型システムとか構文糖に対する態度とかの問題じゃないだろうか。
>>533 >受け取る関数がないならタプルを返す関数はそもそも必要とされないと思う。
そんなことはないだろ。例えばsplitAtの結果のタプルをそのまま別の関数に渡すことは滅多にないと思うが。
>>535 splitAtの結果をfstとかsndとかパターンマッチで分解するでしょ。
この場合fstやsndとかパターンマッチがタプルを受け取る関数ですよ。
fstもsndもタプルのパターンマッチも使わない状況でタプルを返されたとしたら、
それは基本的に必要のないタプルなんだと思うけど。
>>536 そういうことか。分かった。
しかし、
>>529 の文脈
>、ある関数の戻り値が
>タプルの場合、それを受け取れる関数は、引数がタプルである必要があります
>(よね?)。
からして、たぶん
>>532 が言いたいのは、
「ある組合せのタプルを返す関数があったとして、その関数の結果を引数として受け取る関数を書くとき、
その関数を(カリー化された形ではなく)タプルをそのまま受け取るように書くのが普通だ、という理解で良いか?」
だと思う。
uncurryテンプレート書いてみた。 uncurryT :: Int -> ExpQ uncurryT n = lamE [varP f, pat] (rhs n) where f = mkName "f" pat = tupP (map (varP . mkName) ["x" ++ show i | i <- [1 .. n]]) rhs 0 = varE f rhs m = appE (rhs (m-1)) (varE . mkName $ "x" ++ show m)
539 :
529 :2006/07/22(土) 11:05:19
すみません、多忙に付きご返事ができませんでした。皆さんのレスはとても勉
強になりました。ありがとうございます。
標準のHaskellではまだタプルを扱う標準的な方法は無いようなので、私はと
りあえず、必要に応じてuncurry3, uncurry4, ... を作って使うことにします。
>>537 私の意図については、おっしゃるとおりです。私の拙い言葉を補ってい
ただき、大変恐縮です。
>>538 すばらしい!これでuncurryをn個作らなくても良くなるのですね。まだ
私には理解できませんが。
バッカスのFP懐かしす
Mastering Algorithms with Haskell まだー
542 :
デフォルトの名無しさん :2006/07/23(日) 03:08:13
letとガードを同時に使うことはできないのでしょうか? 関数の内容は無意味ですが、例えば f :: Int -> Int f x = let y = x + 1 in | x == 1 = y | otherwise = 0 がsyntax errorになります。 f x = let y = x + 1 in case x of _ | x == 1 -> y | otherwise -> 0 ならいけましたが、見栄えが悪いです。
>>542 where使えばすっきりする。
f x
| x == 1 = y
| otherwise = 0
where
y = x + 1
ありがとうございました
HugsでC++なFFIってできる?
extern "C" すれば
ふつうのHaskellに出てきた、Parsecにハマり中。 最初はよくわからないから、とにかくParserが返す型に注意して、 do 構文も多用しておっかなびっくりコーディングしてたけど、 だんだん慣れてくると、解析したい構文が簡潔明瞭にコードで表現できる ようになってくる。 これマスターすれば、正規表現がいらなくなりそう。 (今はまだ、正規表現のほうが早く書けるけど)
ParsecはLL(1)なので、正規表現以上の解析ができるよ。
表現力では勝るけど、簡潔さにおいては劣るだろ。
で?
ParsecはLL(1)なので、正規表現以上の解析ができるよ。
表現力では勝るけど、簡潔さにおいては劣るだろ。
ふつうのHaskellに出てきた、Parsecにハマり中。 最初はよくわからないから、とにかくParserが返す型に注意して、 do 構文も多用しておっかなびっくりコーディングしてたけど、 だんだん慣れてくると、解析したい構文が簡潔明瞭にコードで表現できる ようになってくる。 これマスターすれば、正規表現がいらなくなりそう。 (今はまだ、正規表現のほうが早く書けるけど)
ParsecはLL(1)なので、正規表現以上の解析ができるよ。
表現力では勝るけど、簡潔さにおいては劣るだろ。
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
ParsecはLL(1)なので、正規表現以上の解析ができるよ。
try演算子があるからLL(∞)だよ。
これからのトレンドはpackrat parsingだよ。
メモリ沢山消費しちゃいます(><;)。>packrat parsing
構わん。好きなだけ使いたまえ。
オバQは絶版ですが何か? > packrat
>>555 コンパイラが文法と型チェックしてくれるのが
うれしい。
>>563 もちろんそうだが、Parsecが正規表現のように簡潔な記法でない以上、
正規表現が要らなくなることはないと言いたかった。
しかし、コンパイル時にパーサの文字列表現を解釈してParsecパーサに変換することも
Template Haskellを使えばできるんだろうな、たぶん。
C++/Boostにはsregexってのがあるな。s=static
正規表現≠文脈自由文法
567 :
デフォルトの名無しさん :2006/07/31(月) 18:10:26
新しい話題は?
multiprocessor版のstableなghcがなかなかでない(work用sourceはあるけど)のは何故? 未だに正式リリースを出せないくらい難しいの?
cygwin上でghc 6.5をコンパイルできた人はいますか?
570 :
425 :2006/08/04(金) 21:13:52
EmEditorのHaskell用構文ファイル作ったけど誰かいる?
>565-571 お前ら……少しは会話しろよw
ViViのHaskell用構文ファイル作ったけど誰かいる?
EmEditor と ViVi の構文ファイルってインデントと色付けしてくれるん?
eclipseのHaskell用構文ファイル作ったけど誰かいる?
俺も作ったよ、それ。2年も前に。
579 :
571 :2006/08/05(土) 21:15:00
サンクス
>577 EclipseFP と比べてどっちが良い?
なんだ色付くだけか・・・
586 :
デフォルトの名無しさん :2006/08/14(月) 01:43:08
perlのsplitみたいな事をhaskellでやりたいんですけど、 自分で関数を定義するしか無いんでしょうか? なんか、すごく遅くなりそうなんですが・・・
split :: Char -> String -> [String] split _ "" = [] split c s = let (l, s') = break (== c) s in l : case s' of [] -> [] (_:s'') -> split c s'' というコードを拾って自己解決しました。
Text.Regex.splitRegex :: Regex -> String -> [String] 使用例 Prelude> Text.Regex.splitRegex (Text.Regex.mkRegex " +") "I am a pen!!" ["I","am","a","pen!!"] なんてのはhoogleをsplitで検索するだけですぐ出てくるのにあ
589 :
デフォルトの名無しさん :2006/08/14(月) 10:00:12
ツンデレめ
あ、そっちの方が便利そうですね。どうもありがとうございまう。 haskell用のgoogle(?)があるんですね。知りませんでした。
591 :
デフォルトの名無しさん :2006/08/19(土) 05:06:26
話題は?
諸君議論したまえよ
皆さん、結局HASKELLの未来はどのように展開されていくとお考えなのでしょうか。 現場レベルで使われるようになるでしょうか? 正直私はそこが知りたい。
594 :
デフォルトの名無しさん :2006/08/19(土) 06:50:24
もっともっと最適化されて枯れてこないと難しいのでわ?
本家のHaskell vs OOPという記事は、 ハスケルにはOOPは必要ないということを言っていますか? O'Haskellという試みもあったようですが、 既にすたれているようですが、それはやっぱり HaskellとOOPが馴染まないという事でしょうか?
596 :
デフォルトの名無しさん :2006/08/19(土) 08:02:35
オブジェクトって状態を持つから純粋関数型とはうまく折り合いつかないんじゃない
HaskellとOOPってそんなになじまないか? 確かに実装の継承やらダウンキャストやらを実現しようとすると大変だけど 「状態をカプセル化し、同一性がある」型は比較的簡単に書ける(標準のHandleが一例)。 存在型を使えば実行時多相も実現できる。
>>596 例えばIOモナドの中で生きるデータはいくらでも状態を持てるんだが。
純粋な関数型ってのは、入出力をする関数にそうでない関数とは
別の型を付けるってだけであって、表現力が変わるわけではないんじゃね?
関数のグルーピングが出来ないって書いてありますよね?
情シス板ってもともと学問カテゴリなんだから 会社・職業のところにITの板新設してドカタを追い出すのが正統だよな
>>602 infosysとinfomaticsは違う板だぞ?
わかってるが、学問カテゴリの板に会社スレが立つ情シスが異常
>>600 1. オブジェクト単位でのグループ分けはできない
2. モジュール単位でのグループ分けができる
3. オブジェクト単位でのグループ分けができないのはまったく大した問題ではない。
と言っている。
個人的には、メソッド名がクラススコープなのは便利なので
これは言い過ぎだと思うが。
ghcで instance (RealFloat a) => Num [a] where [a,b,c] + [d,e,f] = [a+d,b+e,c+f] は出来るのに、 instance (RealFloat a) => Num (a,a,a) where (a,b,c) + (d,e,f) = (a+d,b+e,c+f) は出来ないのかな?仕様を見る限り出来そうな気がするんだけど、なんか間違ってる?
LL Ring に行けなかったんだけど関数型の話面白かった?
612 :
デフォルトの名無しさん :2006/09/03(日) 09:33:41
なんでおまえらそんな物知りなの? 一日中Haskellしてんの?
613 :
デフォルトの名無しさん :2006/09/03(日) 10:07:57
>>612 それは思った。
しかもこの手の言語いじってる奴って大抵メジャーな言語も網羅してるし。
614 :
デフォルトの名無しさん :2006/09/03(日) 12:17:21
もうちょっと最適化が進まないとねぇ… 遅すぎるわ
616 :
デフォルトの名無しさん :2006/09/03(日) 17:33:36
で、おまえら一日中Haskellしてんの?
617 :
615 :2006/09/03(日) 17:45:25
俺は引きこもってずっとコードを書いてたこともあったけど、 そうじゃない偉い人がいっぱいいる気がする。
本物のハッカーはハックをしない
本物のハッカーはエロゲをする
エロゲをしないハッカーは偽者である。
本物のハッカーの家にはフィーナ姫がホームステ(ry
623 :
デフォルトの名無しさん :2006/09/05(火) 18:06:51
諸君議論したまえ
WinHugsで複数行(5行くらい)のプログラムをファイルに保存せずに実行したいんですが、できますか?
625 :
デフォルトの名無しさん :2006/09/05(火) 22:21:45
普段、個人的な作業をこなすのに、haskellつかってる人いますか。 どんなことに使ってますか。
対話環境で電卓
正規表現置換だとややこしくなりそうなのをparsec使って処理してみたりとか
628 :
デフォルトの名無しさん :2006/09/05(火) 23:32:45
ハスケルによるコンパイラ作成入門 って本を誰か出版してくれ
Hakell で文字処理プログラムであるコンパイラって遅そうだな.
コンパイラのボトルネックはそんなところじゃないだろう
631 :
デフォルトの名無しさん :2006/09/06(水) 00:43:22
>>631 first class continuationは?
633 :
デフォルトの名無しさん :2006/09/07(木) 07:55:30
Visual Haskellインスコできなかた
>>628 コンパイラ技法を勉強するだけなら
別に Haskell じゃなくても、
使う言語はなんでもいいんじゃない。疑似言語でも。
Haskell で Haskell コンパイラの話か?
コンパイラ技法の方は知っててHaskellを知らない人のためじゃないか? そっちの方が人口多そうだ。
いわゆるポリモーフィズムみたいなコトをしたいんだけど、 class Animal a where call :: a -> String data Dog = Dog instance Animal Dog where call a = "bowwow" data Sparrow = Sparrow instance Animal Sparrow where call a = "cheep" みたいなのがあって、 animals = [Sparrow, Dog, Sparrow] main = foldr1 (>>) (map (putStrLn . call) animals) だとリストの中身の型が統一されていないってエラーになる。 型クラスはJavaのインターフェイスに似てるって「ふつうの」で読んだけど、 DogもSparrowもAnimalなんだから[Animal]のリストに入れられないの? というかAnimalという型ができるわけじゃないのかな。 自分Java上がりなんだけど、Javaみたいな考え方がHaskellに通用しなくてまいった
>>636 たぶん、
class Animal a where
call :: a -> String
instance Animal Dog where
...
instance Animal Sparrow where
...
として
func :: Animal a => [a] -> String
とした場合、
func :: [Dog] -> String
func :: [Sparrow] -> String
という2つの関数が作られるといった感じの理解のほうが近いように思う。
そして動的に関数を選択するのではなくコンパイル時には
すでに使用される関数は決定しているのだと思う。
クラスの意味としては、
Animalクラスのインスタンスならば、関数callを持っているということが保証される
という感じか。
>>637 そうか、じゃあ[Animal]のリストを作るには
data Animal = Dog | Sparrow
call :: Animal -> String
call Dog = "bowwow"
call Sparrow = "cheep"
animals = [Sparrow, Dog, Sparrow]
main = foldr1 (>>) (map (putStrLn . call) animals)
とやるしかないかな。これだとAnimalに新しい仲間Catが加わったときに
callにも修正が入るよね。
call Cat -> "meow"
を追加し忘れてもコンパイルエラーは出ないし(フラグで警告は出せるらしいけど)、
こういうパターンマッチを全体にばら撒いてしまったら手に負えない。実際さっきそれで苦労してた。
コレだとまるでC言語で巨大なswitch文を書かざるを得なかった時代に逆行してる…
なんとかならんものかな?
まちがい call Cat -> "meow" じゃなかった call Cat = "meow" だ
{-# OPTIONS -fglasgow-exts #-} module Main where import Data.Dynamic data Dog = Ddog String deriving (Show, Typeable) data Sparrow = Dsparrow String deriving (Show, Typeable) class Animal a where call :: a -> String instance Animal Dog where call (Ddog x) = x ++ ": \"bowwow\"" instance Animal Sparrow where call (Dsparrow x) = x ++ ": \"cheep\"" dog x = toDyn $ Ddog x sparrow x = toDyn $ Dsparrow x animals = [dog "pochi", dog "shiro", sparrow "p-ko"] callD x = case show x of "<<Main.Dog>>" -> call (fromDyn x undefined :: Dog) "<<Main.Sparrow>>" -> call (fromDyn x undefined :: Sparrow) main = mapM_ (putStrLn . callD) animals う〜ん、なんか無駄にややこしくなってるだけか。 call (fromDyn x undefined) だけで動いてくれれば良いんだけど、型が曖昧だからダメって言われるんだよな。
たぶんそういうプログラミングスタイルを取るのが問題なんだと思うが、どう したらいいのかは具体例に沿って考えないとよくわからん。型の切取り方がう まくないんだと思うが。 ちなみに、 OCaml では polymorphic variant といって、「拡張可能な data」 みたいなのが簡単に作れる。 Haskell でも HList を使うと polymorphic variant ができるという話。 ただどっちにしても、型エラーが発生したときは死にそうになる。
そもそもクラスの機能の意図が微妙に違うから、多分それができてもどこか別で障害があると思う Monadius見たら weapon = missile | shot | laser ... update missile = ... update laser = ... orz Haskellで綺麗な設計でゲーム作れるんだろうか?
ついでに main = mapM_ (putStrLn . (\(AH x f) -> f x))) animals ですね。
>>643 data AnimalH = forall a. Animal a => AH a (a -> String)
じゃないと文句言われた。(GHC 6.4.2)
>>644 閉じ括弧が1個多い。
ちなみに、↓でもOKだった。
data AnimalH = forall a. Animal a => AH a
animals = [AH Sparrow, AH Dog, AH Sparrow]
main = mapM_ (putStrLn . (\ (AH x) -> call x)) animals
646 :
デフォルトの名無しさん :2006/09/08(金) 00:06:40
諸君、やっと議論を再会してくれたね。
フィーナ姫が月に帰っちゃったから暇になった
>>637-645 凄い、Existentially quantified typesで完全に解決した!感動した!
OCamlやConcurrent Cleanみたいな他の関数型言語を学んでみるのも、
Haskellを使いこなす助けになるみたいだね。そのうちかじってみよう
ついでにmapM_も知ったし、みんなありがと
存在量化(existential quantification)を使わない方法。 data Animal = Animal { animalCall :: String } dog :: Animal dog = Animal { animalCall = "bowwow" } sparrow :: Animal sparrow = Animal { animalCall = "cheep" } animals :: [Animal] animals = [sparrow, dog, sparrow] main = mapM_ (putStrLn . animalCall) animals クラス階層(哺乳類と動物の関係とか)が必要ないなら、こっちが扱いやすいと思う。
>>649 実はそれも考えてたんだけど、dogとsparrowが別の構造を持つと困る。
たとえば、Sparrowは空を飛べるから「飛行高度」みたいなフィールドが必要になったとき、
Animalに追加すると飛べないdogにも追加されてしまって無駄になる。
それが必要なければ649がきっと一番シンプルだよね
久しぶりこのスレが有益な情報に染まっている
それはない
>>651 >>649 のAnimalはインタフェースを表現する型であって、
個々の動物の構造を反映するものじゃない。
「飛行高度」のフィールドをAnimalインタフェースを介してのみ
使う(飛行高度によって鳴き声が異なる、とか)なら
sparrow :: Height -> Animal
を用意するだけで十分だし、専用のインタフェースから使いたいなら、
data Sparrow = {- 専用インタフェース -}
sparrowAsAnimal :: Sparrow -> Animal
で良く、いずれにしてもAnimalの変更は必要ない。
ただし、後者の場合は、
>>649 に書いたように
型クラスを使ったほうが便利かもしれないけど。
>コレだとまるでC言語で巨大なswitch文を書かざるを得なかった時代に逆行してる… 一長一短
オブジェクトがimmutableで、遅延評価されるから
>>654 みたいなのでOKなんだよね。
ダウンキャストしたいとかなると大変なんだけど。
>>654 本当だ。existential quantificationなしでもうまくいった。
代数的データ型をC++/Javaのクラスみたいなものだと思うのが、俺の勘違いの素みたい。
慎重に書いてけばダウンキャスト(?)も必要なさそうだ。
あぁ、感動のあまりもう手元のコードの大半をexistential quantificationで書き換えてしまった。
もっと落ち着いて、それぞれの方法を検討してみることにするよ。
658 :
デフォルトの名無しさん :2006/09/10(日) 15:35:17
ふつうのHaskellを読み出したアホの子に教えてやってください。 emacsのhakell-modeをインストールして main = do cs <- getContents putStr cs と打って2行目でタブを押すとputStr csの先頭がgetContentsの真下にインデントされるんですが、 正しくはcsの真下ですよね? 手動インデントが激しくメンドクサイのですがなんとかならんでしょうか?
>>658 main = do {
cs <-getContents;
putStr cs
}
とすればいいじゃん。
>>660 Emacsのタブインデントはそういうことじゃない。
>>661 python-mode.elやhaskell-mode.elは
タブを押す回数によってインデントのレベルが変る
>>658 の場合
getContents のあと改行してタブを押すと getContents までインデントされる
もう一度タブを押すと cs と同じレベル
次は main が補完される
次は一番外
もう一度押すと getContents までインデントされて以下ループ
使ったことないのに何言ってるの??
(゚Д゚)ガーン 知らなかった。ありがとう。
eclipseのhaskellプラグインないの?
665 :
デフォルトの名無しさん :2006/09/10(日) 21:04:01
ありがと
>>658 ,662
この場合、 turn-on-haskell-indent を
実行することに気付いてないんじゃない?
M-x turn-on-haskell-indent か、hookに入れとく。
# ちなみに、turn-on-haskell-simple-indentっていう、段が変わるだけのもある。
haskell-mode.elの頭にちゃんと書いてある ;; (setq auto-mode-alist ;; (append auto-mode-alist ;; '(("\\.[hg]s$" . haskell-mode) ;; ("\\.hi$" . haskell-mode) ;; ("\\.l[hg]s$" . literate-haskell-mode)))) ;; ;; (autoload 'haskell-mode "haskell-mode" ;; "Major mode for editing Haskell scripts." t) ;; (autoload 'literate-haskell-mode "haskell-mode" ;; "Major mode for editing literate Haskell scripts." t) ;; (add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan) ;; (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) ;; (add-hook 'haskell-mode-hook 'turn-on-haskell-indent) ;; (add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
何が書いてあるのかさっぱりわからない オレには無理みたいだ
EmacsはEmacsHaksellを搭載すべし
Typeableという型クラスがあって、cast :: a->Maybe b というメソッドがある。 これを使えばダウンキャストができる…わけではない。主型はひとつ。
であってる?
ダウンキャストといえばその通りじゃないか? {-# OPTIONS_GHC -fglasgow-exts #-} import Data.Typeable import Data.Maybe data Showable = forall a. (Show a, Typeable a) => S a xs :: [Showable] xs = [S (6::Int), S "foo", S '\^C', S "bar"] fromShowable :: (Typeable a) => Showable -> Maybe a fromShowable (S x) = cast x main = putStrLn $ concat $ catMaybes $ map fromShowable xs
675 :
sage :2006/09/15(金) 12:29:37
674 って、main を実行するとどう表示されるの? てもとに ghc がなくてわからん。解説きぼんぬ。
>>675 "foobar"と出た
concatがString要求してるからfromShowableがShowable->Maybe Stringになるらしい
catMaybesでStringにならなかったやつは消える
結局元々Stringだったのが残る
>>676 細かいがStringを要求しているのはputStrLnね
data NumberOrString = Number Int | String String cmp :: (Ord a) => (a -> a -> Bool) -> NumberOrString -> NumberOrString -> Maybe Bool cmp op (Number n) (Number m) = Just $ op n m cmp op (String s) (String t) = Just $ op s t cmp _ _ _ = Nothing こんな関数を作ろうと思ったんですが Couldn't match the rigid variable `a' against `Int' ... と出てきてコンパイルできません。このような関数を定義するにはどうしたらいいんでしょうか?
>>678 たぶん、やりたいことと型が合っていない。
その型だと、型変数aにはOrdのインスタンスであればどんな型でも代入できるから、
例えば、aにDoubleを代入した
(Double -> Double -> Bool) -> NumberOrString -> NumberOrString -> Maybe Bool
も、cmpの型の一つということになる。
つまり、opとしてDouble -> Double -> Boolの関数を渡せる訳だが、
これは意図したことじゃないだろう。
opとして「全てのOrdのインスタンスに適用できる関数」を期待するなら、
GHCやHugsでは、rank-2 polymorphismという拡張を使って、次のように書ける。
cmp :: (forall a. (Ord a) => a -> a -> Bool) -> NumberOrString -> NumberOrString -> Maybe Bool
ちなみに、この記法で元のcmpの型を表記すると、
cmp :: forall a. (Ord a) => (a -> a -> Bool) -> NumberOrString -> NumberOrString -> Maybe Bool
となって、変数aの全称量化のされかたが違うことが分かる。
お前ら本当は俺って難しそうな言語をやってるんだぜって感じで人に自慢したいだけでHaskellやってんじゃね?
>>680 なんか動機とははそれでも良いじゃないと思うオレ
格好からはいるのが悪とは思ってないしモチベーションになればいいかなと
上の会話が理解出来るくらいのレベルになりたいなぁ
たぶん Haskell の理解度と言うよりプログラマとしてある程度のレベルに達してないとダメだろうなぁ
もっと頑張らないと
まあHaskellの型の表現力が弱いから、無駄に複雑になってる気もするけどね。 forall a in { Int, String }. ... と書けるdecidableな型systemがあれば何の問題もなかった。
683 :
デフォルトの名無しさん :2006/09/18(月) 10:20:58
ハスケルなんか糞
>>680 だけじゃないけど、正直それもあるw
メジャーなパラダイムや言語は押えておきたいというのが主な理由。
仕事で使うことは無さそうだけど、考え方の幅は広がるだろうから。
>>680 おれの場合きちんと大学とかで計算機科学やってないから、
コンプレックスがあるんだよね。Haskell やるより計算機科学の
教科書マジメに読んだほうが早いかもしれないけど、
新しい概念を追いつづけるのは楽しいし格好良いと信じてる。
Haskell やるより 計算機科学を学んだほうがいい。 子どものときは大人のアドバイスは聞かないが。
>>686 その大人のアドバイスは子供の性質を考慮していないオナニーアドバイスだからだよ。
要するに好奇心旺盛な子供には、Haskellを通じてどうやって計算機科学を教えるかを考えるべきだ。
(<|>) なんかエロい構文
好奇心旺盛な子供だったら、 Haskellの勉強を片手間にしつつ 計算機科学の勉強を勝手にHaskellと 関連付けながらしっかりこなせる。 難しいのは、好奇心が半端な子供へのアドバイスだ。 で、それとは別の話で、計算機科学の勉強したいだけなら、 どっかで教科書指定されてるような大きい本を買ってきて 一通り読んで、基本情報処理技術者試験でもうければいいよ。 どうせ基礎教養のようなもんだから、一通り触っておけば十分だろ。 その基礎を完璧に固めるのは結構苦労するけど。
おれの場合好奇心は少年並にあるぜ 仕事ばっかで時間がないけど… SICP みたいな質のたかーいじっくり楽しめるハスケル本希望。
まぁそこまで頭良くないからとっかかりとして一つだけでも良いじゃないと思う 人それぞれ何じゃないかなぁ それ以上言っちゃうと言葉遊びになっちゃうよ
> 仕事ばっかで時間がないけど… これは忘れてた。 暇人じゃないとなると量をこなす必要のある勉強はなかなか難しいよな。
>>692 毎日時間決めてやれば問題ない。
俺とかおまえみたいに2chにきてる様じゃ駄目だろうけどな。orz
>>693 でも2ch以外にHaskellの情報源なんて無くね?
696 :
デフォルトの名無しさん :2006/09/23(土) 13:12:05
データ(構造)に、ある性質を保証するってどうやるの? たとえば、必ず昇順になってるリストとか。 普通?の言語だと、操作もコンストラクタも自在だから、 性質を保つ操作だけ提供して、コンストラクタは空か最初にソートすればいい。 でもHaskellだと、データ構築子使って、 性質に違反した値をリテラルみたいに書けちゃうのを禁止できなくない?
698 :
デフォルトの名無しさん :2006/09/23(土) 15:22:41
なるほど。 モジュールで、データ構築子を隠して関数の利用を強制できるのか。 サンクス。
haskell入門買ったばっかの素人(一応lispは知ってる)だけど、 haskell ってパーサーの構築に似てるとオモタ。 perl の RecDescent にそっくり。
WinHugs-Sep2006が出てた。 アンインストーラがまともに動かんけど。
ghc 6.5はまだか
ghc の freebsd amd64 対応はまだか
ghcのmulti processor対応版のbinaryはまだか
704 :
デフォルトの名無しさん :2006/09/29(金) 12:29:03
>>697 自分でコントロールできる型はいいけど、
クラスのインスタンスが、単に必要なメソッドを提供するだけじゃなくて、
クラスが求める制約を満たす、って出来ないのかな。
モナド則を満たさないでMonadインスタンス作ったらコンパイルエラーとか。
プログラム停止性問題とか絡むのかな?
haskel、関数名がキャメルノーテーションなのどうにかしてくれ どうせソースの見た目が奇妙なんだから関数名も奇妙にしてほしい
具体的に何がイヤでどう変えると良いのか一事例でもいいんで教えてくれ。
>>705 同感。
下線区切りかハイフン区切りか、せめて全部小文字にして、
CやPerlみたいに短い名前を使ってほしい。
>>706 例えばopenFileはopen_fileかopenfileかfopenにして欲しい。
ええー 俺はopenFileが一番好き
camelWordの方が読みやすいけどなあ
>707 関数名も奇妙に、っていうのはそれでいうとどれ? fopen みたいなのを想定 してたのかな。 おれは openFile の方がいいよ。 CamelCase か下線区切りか、みたいなのはどっちでもいいんだが、短い名前で 省略するよりは冗長な方がずっといい。
漏れは APL みたいに記号になっちゃってるのが好き。
712 :
707 :2006/09/29(金) 21:16:40
>>704 例えば↓みたいなのがモナド則を満たすかどうかをチェックできないと駄目なわけだよね。
import System.Random
import System.IO.Unsafe
import Control.Exception
data BadMonad a = X a | Y a deriving Show
instance Monad BadMonad where
return x = rndChg (X x)
X a >>= f = rndChg (f a)
Y a >>= f = rndChg (f a)
rndChgIO = randomIO >>= \ b -> return $ if b then id else chg
rndChg = unsafePerformIO rndChgIO
chg (X x) = Y x
chg (Y y) = X y
data BadMaybe a = BJust a | BNothing deriving Show
instance Monad BadMaybe where
return = dontStop . BJust
BJust a >>= f = dontStop $ f a
BNothing >>= f = dontStop $ BNothing
dontStop x = unsafePerformIO ( evaluate (reverse [0..]) >> return x )
BadMonadはたまに満たしちゃうこともある。
BadMaybeは一応満たすんだけどまじめに評価すると止まらない。
714 :
705 :2006/09/29(金) 22:41:39
例えばfoldとかzipWithとか使用頻度高いのに普通すぎ、かつ短いのに分かりにくい名前だと思う fold は->((/)) とか激しい記号にしてほしい
高階関数はschemeなんかと同じほうがわかりやすい
むぜえええええええええええええええええ!!!!
fold とか zip がわかりづらいという感性がわからん 714の記号は何を意味していてどこがわかりやすいのかな。
foldは(| a, h |)のようなdistfix operatorだったら良かった。
>>714 親切丁寧なライブラリがあった方が嬉しい。
>>714 とか見ると、
>>680 も宜なるかな、と思わざるを得ない。
ところで、みんなは、日本語どうしてるの?
UTF-8を10進リテラルで埋め込んでる。
UCS2じゃないの? つうか、コードの中じゃなくて、IOだよIO。
>>721 EUCでソースを保存してiconvで変換
>>723 使いたい文字コードをCharひとつに1バイトずつ埋め込んでおけば
とりあえずIOは通る。汚いけど。
俺の場合はたまたまその文字コードがUTF-8だっただけ。
726 :
ニュース速報+ :2006/09/30(土) 15:17:35
いや、ソースの話じゃなくて、getContentとか、hPutStrとかだよ。 Charが16bitのくせに、こいつら1バイト単位じゃない? これでどうやって日本語ファイルを扱えるようにするかって事。 初心者だから間違ってたらスマン。
>>727 CharはUnicodeのコードポイントを表す型だけど、
GHCのIOライブラリは、まるでエンコードされた文字列のうちの一バイトを
表す型であるかのように扱う。
例えば、日本語版Windowsで、sjisで「欠席」とだけ書かれたファイルをreadFileした場合、
['\27424', '\24109']
が返るのが正しいが、実際は
['\140', '\135', '\144', '\200']
が返る。同様に、writeFileで「欠席」と書かれたファイルを作りたいなら、
['\140', '\135', '\144', '\200']を渡さないといけない。
>>724-725 は、この挙動に合わせて、Charを1バイトを表す型として使っている。
ついでに言うと、
>Charが16bitのくせに
Charは21ビット。
>ソースの話じゃなくて、getContentとか、hPutStrとかだよ。 そんなこと一言も聞いてないが
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/haskell/haskell-jp/403 にあるIconv.hsc使ってる。ただ、このバージョンだとメモリリークするバグがあるので次のようにして直す(他にも[Word8]ではなく、StringからStringに変換する関数を追加してる)。
19c19
< module Iconv
---
> module Text.Iconv
25a26
> , iconvString
27c28
<
---
> , convertString
36c37,38
< import Monad (liftM)
---
> import Control.Monad (liftM)
> import Control.Exception (evaluate)
111a114,119
> iconvString :: Iconv -> String -> IO (String, Maybe Error)
> iconvString iconvData str
> = do
> (r, e) <- iconv iconvData (map (toEnum . fromEnum) str)
> return (map (toEnum . fromEnum) r, e)
>
続き 173c181,185 < where loop cd [] = unsafePerformIO (reset cd) --- > where loop cd [] = unsafePerformIO (do > result <- reset cd > evaluate reset > close cd > return result) 193a206,212 > convertString :: String -> String -> String -> (String, Maybe Error) > convertString from to str > = let > (r, e) = convert from to (map (toEnum . fromEnum) str) > in > (map (toEnum . fromEnum) r, e) > 252a272 >
単純に1バイトずつしか読まない・書かないんだから、それを逆手にとって、
単なるバイト列としてエンコード・デコード関数を用意すればOKって事だな。
って、
>>730 がそれか。超サンクス!
しかし、こんなの処理系が標準で備えるべきモノじゃないか?
なんで未だにこんな基本的な機能もないんだ?
>Charは21ビット。
リアルUnicode(を想定)してるのか。そんな贅沢してるんなら、ちゃんと符号化もやれよw
Hugsはロケールのエンコーディングで書かれた文字列を読み込むとUnicodeに自動変換される。 まあ結局GHCと合せるためにhSetBinaryModeでTrueを指定するんだけど。XMLとか扱うときはロケール意外のエンコーディングも使いたいし。 あと、話は変わるけど、HaXMLはISO-2022-JPに対応していない(2バイト文字が'<'などを含むため)。一旦Unicodeとかに変換しないと
日本語なんて使わなければすべて解決
ghcなんて使わなければすべて解決
take 0 _ = [] take n (x:xs) = x: take (n-1) xs という定義に対して、ghci(6.4.2)で > take 10 [1,2] [1,2] > take (-1) [1,2] [1] となります。 どっちも、take (非0) [] まで進んで、これはどっちにもマッチしなくてエラーになると思うのですが。 []が(x:xs)にマッチするとしても、10はxとxsがどうなるのか…。
737 :
デフォルトの名無しさん :2006/10/01(日) 06:41:48
なりません。 myTake 0 _ = [] myTake n (x:xs) = x:myTake (n-1) xs >myTake 10 [1,2] Excertion (略) : Non-exhaustive patterns in function myTake
738 :
736 :2006/10/01(日) 07:04:02
いや、マジでなるんですけど…。
D:\study\haskell>type aa.hs
mytake 0 _ = []
mytake n (x:xs) = x: take (n-1) xs
D:\study\haskell>ghci aa.hs
___ ___ _
/ _ \ /\ /\/ __(_)
/ /_\// /_/ / / | | GHC Interactive, version 6.4.2, for Haskell 98.
/ /_\\/ __ / /___| |
http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help.
Loading package base-1.0 ... linking ... done.
Compiling Main ( aa.hs, interpreted )
Ok, modules loaded: Main.
*Main> mytake 10 [1,2]
[1,2]
*Main> mytake (-1) [1,2]
[1]
*Main>
>>738 > mytake n (x:xs) = x: take (n-1) xs
mytakeであるべきところがtakeになってるから。
HugsのPrelude.hsを見ると、takeの定義は下のようになってて、
第一引数が負の時は[]が返る。
take :: Int -> [a] -> [a]
take n _ | n <= 0 = []
take _ [] = []
take n (x:xs) = x : take (n-1) xs
mytakeがmistakeに見えた・・・
可変長配列みたいなことがやってみたいと思ってこんなコードを書いたんですが、 やっぱ無理ですた。 createList a b = createList (a:b) createList a = a:[] main = print ((createList 1 2 3 4) :: [Int]) なんかいい方法ないですかね?
>>741 可変長引数のこと?
それならHaskellでは基本的に書けない。
基本的にってことは、例外的に可変個引数の関数を書く方法はあるってことでしょうか?
リストとか Maybe とかで擬似的に可変長引数みたいなものを実現するということだろう。 ところでその createList というのは、どういう型をもつのか考えたことあるのかな。 また、createList 1 というのが [1] になるべきか (\b -> 1:b) になるべきか、 というのはどう決定されるべきだと考えてるのかな。
745 :
741 :2006/10/01(日) 15:52:56
>>744 > createList 1 というのが [1] になるべきか (\b -> 1:b) になるべきか、
もちろん[1]になることを期待しました。
mainの方で[Int]としたのはうまいこと推論してくれるかな?と。
>>742 > 可変長引数のこと?
そうです。単なる書き間違いです。
>>746 ヘタれな私にはムズいです。
じっくり取り組んでみます。
ありがとうございました。
日本人は低能知能なのには呆れますね。 私達中華人民はあなたたちの掲示板を拝見して笑ってみてますよ。ではありがとうございました。
>>749 なるほど!引数の数によって型も変えちゃうようなイメージやね。
これならできそう。がんばってみる。
>>749 の例に
instance VAFun a [Int] [Int] where
withVAList g = g []
createList :: VAFun Int [Int] x => x
createList = withVAList id
を加えてやるとInt型限定のcreateListができた。
createList (1::Int) (2::Int) (3::Int) :: [Int]
=> [1,2,3]
>>751 > createList :: VAFun Int [Int] x => x
この型の意味がわからん。
ふつけるを読み返しては見たんだが…
xがVAFun か Int か [Int] って意味でいいのか?
> instance VAFun a [Int] [Int] where
こっちはますますわからん。
[Int]をふたつ渡すとVAFunになるような型ってことかな?
>>749 そのサイトにあるこの表現、
class VAFun a r f | f -> r where
この縦棒(←記号名を忘れた)は「または」の意味でいいんだよな?
ふつけると入門Haskellを読み返したがそういう表現は無かったので、
念のため確認。
>>754 まだ詳しくは読んでないけど、hugsとghcの拡張機能だと思う。
>>753 VAFunは3引数の型クラス。(多引数の型クラスはHaskell98にはない)
VAFun a b cという条件は、a, b, cの三つ組がVaFunのインスタンスである、という条件を表す。
だから、
createList :: VAFun Int [Int] x => x
は、Int, [Int], xの三つ組がVaFunのインスタンスであるような全てのxについて、
createListはその型を取り得る、というように読む。
>>754 「| f -> r」の部分は、「ただし、fが決まればrはただ一つ決まる」という意味。
関数従属(functional dependency)といって、これもHaskell98にはない。
Type Classes with Functional Dependencies
http://web.cecs.pdx.edu/~mpj/pubs/fundeps.html
>>755 ghcを使ってるんだけど、エラーで
Use -fglasgow-exts to allow multi-parameter classes
って出たのでどうやらそのとおり拡張らしい。
>>756 > 「| f -> r」の部分は、「ただし、fが決まればrはただ一つ決まる」という意味。
ただ一つ決まるというのはただ一つの型に決まるということですよね?
URIまで示してもらって悪いんですが、英語に明るくない私にはそこまで読み取れないので。
>ただ一つ決まるというのはただ一つの型に決まるということですよね? そういうこと。 例えば、 instance VAFun a Int Int where と instance VAFun a Char Int where の二つのインスタンス宣言があったとすると、fがIntのときrが一つに決まらない (IntでもCharでもあり得る)から、コンパイルエラーになる。 その代わり、関数従属を指定したことで、withVAList sumの型である (VAFun a a f, Num a) => f が「意味のある」型になる。もしfからaが決まらないなら、 aを具体的に指定するすべががなく、この型は使いものにならない。
このスレでいいのかわからないけど、 Meadowでhaskel-modeでC-c C-lとかC-c C-rとかで帰ってこなくなることないですか? ghc.exeがずっとCPU占有状態。ghc.exeが二つあることもあるような。
ありがとうございます。 でも、バッファの内容は、実行(評価?)を含まず、 定義だけなので実行が無限ループはしてないと思います。 (初心者で判ってないので変な事言ってたらすみません)
762 :
あげ :2006/10/05(木) 20:30:46
あげ
遅延評価って具体的にどういう順で評価されるんですか? 普通に前から結合順位が高いもの順?それを必要な分だけ進める感じ? IOの>>や>>=をどういう風に組み立てればいいのかよく解らないので。
ついでに IO 動作の実行順序と評価の順序をごっちゃにしてはいけないよ。
>>763 評価の順序は、外から順。
f (g (h x))という式なら、まずfが呼ばれる。
1 + 3 * 2という式なら、これは(+) 1 ((*) 3 2)のことだから、まず(+)が呼ばれる。
ただし、結果が同じである限り、処理系は別の順序で評価するかもしれない。
>>や>>=を使ったときのIOの実行順序は、左から右。
これは評価順序とは関係なく、>>=の仕様がそうなっているというだけ。
つまり、 評価順は基本的に外からだけど不定、IOの>>や>>=は評価順に関係なく左から右 ということ? >>や>>=も単なる関数だと思うんだけど、評価と関係なく左からってなんで出来るの? IOだけ評価とは別の機構で順番が決まるの?
評価と実行は別物
言語上の進行と切り離されたキューがあって、 >>=や>>の評価毎に、実行すべきモノがたまって行く、 ってイメージだったんだけど、全然違う? 構文解析後に、評価とは別に、そこに表れてる>>や>>=を左から順序が決まる、ということ? 式には直接表れていないけど、変数に含まれてる>>や>>=の順番は? それって、変数を評価してみないと判らないと思うんですが。
>>767 IO a型の値(動作と呼ぶ)は単なるデータで、それ自体が何かをする訳ではない。
例えば、getLine :: IO Stringは「標準入力から一行読むこと」を表すデータに過ぎないので、
getLineを評価しても何も起こらない。(これは、1 + 1を評価しても何も起こらない、というのと同じ)
同様に、putStrLn "Hello"を評価しても、「標準出力にHelloと表示すること」というデータが返ってくるだけで、
実際にHelloが出力される訳ではない。
ではどうやって実際に動作を実行するかというと、mainを実行したい値に束縛すれば良い。
Haskell処理系は、mainの値(mainの型はIO aなので、これは動作)を実際に実行する。
これ以外に動作を実行する方法はない。
(>>)は、二つの動作を組み合わせて一つの動作にする関数。
具体的には、
a >> b
は、
「aを実行し、次にbを実行すること」
を表す動作になる。(>>)はあくまで動作というデータ間の演算であり、
実際に動作を実行する訳ではないことに注意して欲しい。
ここで、aとbを評価する順序は未規定だが、
どうせ評価しても何も起こらないので、大した問題ではない。
なるほど、上で「左から右」って書いてある意味は、「>>=や>>の左辺→右辺」という意味ですね。 実行すべきモノのキューというより連結可能なリストが、IOモナド毎にあって、 最終的に>>や>>=による合成で出来たIOモナドのタスクリストが実行される。 評価順の不定があっても、出来るIOモナド(の実行足す栗須と)は同じだから問題ない、 というところでしょうか。
>>771 そんな感じかな。
f _ a=a
main=f (putStrLn "hello") (putStrLn "world")
とか
main=seq (putStrLn "hello") (putStrLn "world")
とかやってもhelloは出力されないし。
>>770 ただ(>>)と(>>=)の動作はIOモナド限定ね。
ありがとうございます。でもやっぱり判らない…。 mySequence [] = return [] mySequence (x:xs) = x >>= (\h -> mySequence xs >>= (\t -> return (h : t))) と定義して、 mySequence [putChar 'a', putChar 'b', putChar 'c'] は、abcと出力しました。 でも、>>=がふたつあります。 前の>>=はxの文字の1文字出力、後の>>=はxsの文字列出力を作るので、 それぞれの文字は、文字としてと、連結途中の文字列として、の複数回出力される気がするのですが。
>>773 >前の>>=はxの文字の1文字出力、後の>>=はxsの文字列出力を作るので、
前の>>=について、左辺はxの一文字出力で、
右辺はxsの文字列出力だから、結果は(x:xs)の文字列出力になる。
前の>>=の結果がmySequenceの結果だから、mySequenceの結果も(x:xs)の文字列出力。
>>773 mySequence [putChar 'a', putChar 'b', putChar 'c'] を定義に従って展開していくと、
最終的にはこんな感じのになる。
putChar 'a' >>= (\ha -> putChar 'b' >>= (\hb -> putChar 'c' >>= (\hc -> return (ha:hb:hc:[]))))
System.Win32のリファレンスってwebにある?
>773 x は「1文字出力の動作」だけど、 h は動作じゃなくて動作結果。でその動作 結果の値を受け取って return しているが、これは「値を返すという動作」な ので出力動作はされない。 x という動作は1回しか実行されていないから問題なし。
ありがとうございます。 putChar 'a' >>= (\ha -> putChar 'b' >>= (\hb -> putChar 'c' >>= (\hc -> return (ha:hb:hc:[])))) で、 return (ha:hb:hc:[]) は、「"abc"を出力する動作」で、これが返り値。でも、その返り値は使われてない。 3つの>>=によって「'a'を出力する処理」「'b'出力する処理」「'c'出力する処理」がこの順で実際に実行される。 と言うことですね。 しかし、その形に展開する過程で、たとえば、 mySequence (putChar 'c':[]) = putChar 'c' >>= (\hc -> (return []) >>= (\tc -> return ('c' : tc))) ↓ mySequence (putChar 'c':[]) = putChar 'c' >>= (\hc -> return ('c':[])) のような展開がありました。 この展開で>>=によって、[]を出力する事になってしまわないのでしょうか。 ここでは[]ですが、ほかに、"c"と"bc"が出力されるような展開がありました。 これらの出力実行はどうなってしまったのでしょうか。展開と評価は別? 展開ってなんでしょう? 評価と同様に、実際に>>=の定義によってなされるものですよね?
あ、考えたら、やっぱりこれは展開というより等価だから評価ですよね? mySequence (putChar 'c':[]) = putChar 'c' >>= (\hc -> (return []) >>= (\tc -> return ('c' : tc))) = putChar 'c' >>= (\hc -> return ('c':[])) これは手でやったんですが、 モナド則の(return a) >>=f = f aを念頭に置いてこう変換しました。 モナド則って処理系に入ってるものじゃなくて、>>=の定義が満たしているだけのモノですよね? つまり、この変換は、>>=を評価することでしか処理系ではなしえないと思うのですが。
>>778 >return (ha:hb:hc:[]) は、「"abc"を出力する動作」で、これが返り値。でも、その返り値は使われてない。
違う。return (ha:hb:hc:[])は、「なにもしない動作」で、(ha:hb:hc:[])が返り値。
一般にreturnは何もしない動作を表すw。
>>778-779 展開がおかしい。
まず、mySequenceの定義から
mySequence (putChar 'c':[])
= putChar 'c' >>= (\h -> mySequence [] >>= (\t -> return (h:t)))
= putChar 'c' >>= (\h -> return [] >>= (\t -> return (h:t)))
ここで、モナド則から
return [] >>= (\t -> return (h:t))
= return (h:[])
よって、
mySequence (putChar 'c':[])
= putChar 'c' >>= (\h -> return (h:[]))
ちなみに、putChar 'c' の型は IO () なので、hに代入されるのは'c'ではなく () 。
なので、mySequence [putChar 'a', 略] >>= print とすると、
abc[(),(),()]と表示される。
>>780 なるほど。IOのreturnを勘違いしていたんですね。
return (ha:hb:hc:[])は、[ha,hb,hc]に「なにもしない動作」がくっついたもの、ですね?
>>781 モナド則は、>>=の定義が従っているだけですよね?
つまりモナド則を使った展開では>>=が評価されてるんですよね?
そのとき、「左辺処理=[]を何もしない」の後に「右辺処理=(h:t)を何もしない」がされる事になる。
でいいんでしょうか。
putChar 'c'の値自体は、カス()に「'c'出力処理」が付いたものであって、
'c'に「出力処理」が付いたものではないんですね。とんでもない勘違いをしていましたね…。
だから、>>=の右辺に渡されるのはカス()だけ、と。
やっとたどり着いた気がします。ありがとうございました。
俺まとめ。 SMPサポート: スレッドの並列実行とControl.Parallelのプリミティブによる並列評価 LANGUAGEプラグマ: 使われている言語拡張を明示して、OPTIONS_GHCの代わりに びっくりパターン: 正格な関数が書きやすくなった Text.Reget.Posix: if str =~ "^[a-z_][a-zA-Z0-9'_]*$" then .. Data.ByteString: 効率の良いバイト列/8ビット文字列 Data.Sequence: updateを含む数多くの操作をそれなりに効率よくこなすリスト代替コンテナ :mainコマンド: ghciで、引数つきでmainを実行 impredicative polymorphism: [forall a. (Show a) => a -> String] UTF-8ソースファイル: ∀a. a → a Data.Foldable: foldの任意のコンテナへの一般化 Data.Traversable: よくわからん Control.Monad.Instances: Functor ((,) a) Foreign.ForeignPtr: 終了子に余分な引数を与えられるようになった Data.Array.Storable.unsafeForeignPtrToStorableArray
正直Haskell興味あるんだけどほかのプログラムと連携できないと意味ないのでHaskell.NET激しくきぼん・・・
実行スピードがいまいちなのってコンパイラの最適化が甘いせいだよね?まさか言語仕様のせい?
乙。 >UTF-8ソースファイル ソースだけかよ…。orz
あのモノリシックなIOライブラリにコード変換を入れる気はおきないんだろう。 むしろ新しいIOライブラリ(Streamsとか)の整備待ちのような気もする。
ghciでの、tab補間がうれしい。
>>790 それじゃもっとひどいじゃねぇか。
中途半端イヤ!
>790 hPutChar が各文字を castCharToCChar していて、コードポイントが 0xff を 越える文字はその時点で丸められるという話だな。 ただ、 putStr でこれに対応してしまうと、今度はバイナリデータが扱えなく なるので、現状の方がまだマシ。 ただ文字列→UTF-8文字列の変換が標準で欲しいのは確か。
>ただ、 putStr でこれに対応してしまうと、今度はバイナリデータが扱えなく putStrはHandleがバイナリモードかどうか知ってるんだから、その点は問題ないと思う。 むしろ、ロケールにかかわらずUTF-8で出力されるとしたらそっちが問題だろう。
>794 バイナリモードは Windows で改行コードを扱えるようにするだけのモードと いう認識なんだがそこまでやるかなぁ。 で、文字コードやロケールなどを考慮に入れると、現状の枠組みでは弱すぎる と思う。無理にあれこれいじるよりはむしろ Streams のような(ssc の方が近 いか)仕組みを採用する方向に持っていった方がいいんじゃないかな。
バイナリデータとUTF-8が扱えればとりあえず十分だと思う。 UTF-8で出力出来れば、別のプログラム(文字コード変換とか)をパイプで繋げば良いし。
バイナリに関してはByteStringを使えば良いんじゃないかと思う。
>>787 どの言語のなんてコンパイラとどういう比較をして
どのくらいいまいちだったの?
比較するのに使ったソースと比較結果とかをだしてちょ
Hugsはバイナリモードじゃない場合ロケールのエンコーディングからUnicodeに変換しようとするね。
>>798 Haskellはモナドと浮動小数演算が遅い
これは常識
モナドが遅い?
文字列操作も遅かった。
ghcの起動も遅い
文字列操作が遅いのは確かだ。 浮動小数演算の速度を確かめてみた。 main = print $ itermult 10000000 1.9 itermult :: Int -> Double -> Double itermult 0 x = x itermult n x = itermult (n-1) (x * 1.000001) こんなコードを実行すると、Cで書いた場合を1として、 7 (ghc-6.4.2) 3 (ghc-6.4.2 -fexcess-precision) 6 (ghc-6.6rc2) 6 (ghc-6.6rc2 -fexcess-precision) の時間が掛かった。同様のコードを整数について書いた場合、Cに比べて25%ほど遅かった。 ちなみに、GHCの正確性解析はitermultが両方の引数について正格であると 正しく判断しているので、無駄な遅延が原因ではない。 モナドが遅いってのは意味が分からん。どのモナド?
ファイルの読み書きとかIOUArrayとかだろ
806 :
デフォルトの名無しさん :2006/10/13(金) 15:24:28
ghcのコンパイルが遅い
ああ、ghc「の」コンパイルか。
たしかにghcソースからいれると一時間以上かかる
一時間くらいで終わるとは、ずいぶん良いマシン使ってるなあ
Athlon64 4800+
ghcはsourceが巨大な上、build過程も複雑極まりない。 windows上でbuildするのは不可能に近い。 そろそろ整理し直した方がいいんじゃないか?
まあ確かにややこしいけれど、整理するだけでそんなにわかりやすくなるよう なものなのかな? そこのところがよくわからないな。どう整理したらいいと 思う? あと、 building manual には、 Windows に関するわりと詳細な記述があるよ うに思うけど、それでも不可能に近いものなの?
>>812 そうなの?ふつうにコマンド一発で出来たと思うが。
そんなことよりクロスコンパイラを作れないことが問題だ。
確かにwindowsでコンパイルできた、という人は聞いたことないな。 俺も挫折した。
試しにmingw+msys上でconfigure; makeしてみたんだけど、 libHSbase.aを作るところで一度に渡すファイル数が多すぎるか何かでこけた。 一旦渡すべきファイルのリストをファイルに書き出して ar q libHSbase.a @ファイルリスト としてやれば作れたんだけど、 その後もlibHSbase_p.a作るところで同じ理由でこけて、 なんかやる気がなくなった。
で、GHC6.6にアップデートした方がいい?
>>818 詳しくみてないがエラストテネスのふるいが3割速くなった
>>819 凄いな。
ついでにエラトステネスのふるいも計測してみて
main = print $ f [2..] !! 7000 where f (x:xs) = x : f [y | y <- xs, y `mod` x /= 0] これで -O3 つけてコンパイルで 6.4.2 ./a.out 7.000s user 0.020s kernel 99% cpu 7.045s real 6.6 ./a.out 10.369s user 0.012s kernel 99% cpu 10.397s real
逆だね
整数演算は元から速いから、あまり意味ないかも
不必要な評価をさらになくせたから速くなったの?
gccが速くなった結果かも
826 :
デフォルトの名無しさん :2006/10/16(月) 23:38:22
Haskell勉強中の者です。こんなコードを書いて、 f :: (Num a) => (a -> a) -> a f k = g 10 where g :: (Num a) => a -> a g = k main = print $ f id GHCでコンパイルすると、下のようなエラーになってしまいます (gの型を明示的に書かなければコンパイルできます)。 「gの型のaは、fのaと同じ」ということが記述できれば解決するような 気がするのですが、なにかうまい方法はありますでしょうか? where節の関数の型は書かないのが普通なのでしょうか? test.hs:6:2: Inferred type is less polymorphic than expected Quantified type variable `a' is mentioned in the environment: k :: a -> a (bound at test.hs:3:2) When trying to generalise the type inferred for `g' Signature type: forall a. (Num a) => a -> a Type to generalise: a -> a In the type signature for `g' When generalising the type(s) for `g'
>>826 そのままコピペするとインデントが無くなるので書き込むときには注意。
↑これってテンプレに入れといた方がよくね?
まぁその程度で意味不明になるほどのコードは今のところそうそう出てきてないけど。
828 :
826 :2006/10/16(月) 23:54:01
>>827 スミマセン。3行目から5行目まで、行頭にTAB一つ入ってるということで
お願いします。
830 :
826 :2006/10/17(火) 00:03:50
>>829 え?それのどこがミスなんでしょうか。
正しい例を教えていただければ助かります。
829は放置で。
Num ⊃ Int 。 だから、 f :: (Int -> Int) -> Int f k = g 10 where g :: Int -> Int g = k とか、 f :: (Char -> Char) -> Char f k = g 'a' where g :: Char -> Char g = k だと、うまくいくでしょ。
Num ⊃ Int ⊃ 10 と書いた方がいいかな。 ってまあ、俺の方が初心者だと思うので、嘘言ってたらゴメン。
>834 いけました!ありがとうございます。
Int 投げんなよ。
内部でロケール依存の変換をするIOライブラリを書いてみた。
やっつけだけど、良かったらどうぞ。
http://yogimo.sakura.ne.jp/ssc/ssc-0.0.9.tar.gz 使い方 (ghc-6.4.2以上が必要)
アーカイブを展開して、そこに移動し、
runhaskell Setup.lhs configure
runhaskell Setup.lhs build
runhaskell Setup.lhs install
でインストールできる。アンインストールは、
runhaskell Setup.lhs unregister
してから、インストール先のディレクトリ(インストール時に表示される)を手で削除。
使いたいときは、モジュールの先頭に
import System.IO.SSC.Haskell98
import Prelude hiding(putChar, putStr, putStrLn, print, getChar,
getLine, getContents, interact, readFile, writeFile, appendFile, readLn)
と書いておけば、標準のライブラリよりも優先して使われる。
インタフェースはSystem.IOと同じなので、特にいろいろ考えることなく使える。
main = putStrLn "諸行無常のHELLO WORLD"
とか。ただし、このライブラリのHandleは標準のHandleと互換性がないので注意。
>>837 WinXP, GHC 6.6で試してみました。
GHCiで837のコードを動かしてみたら見事に化けました。
GHCiはコードページを28591に変えちゃうんで
cmd.exeでラスタフォントを使ってる場合は化けて当然なわけですが、
一旦フォントをTrueTypeFontに変更してGHCiを起動、:! chcp 65001で
UTF-8のコードページに変えると、
sHELLO WORLD
O WORLD
という表示になりました。
まぁ、CP932(Shift JIS)に変更してやればきちんと表示されましたけど。
ちなみに、ファイルにリダイレクトさせると、コードページが何であってもShift JISで出力されてました。
Stateのサンプルコードがわからんです。 tick :: State Int Int tick = do n <- get put (n+1) return n plusOne :: Int -> Int plusOne n = execState tick n 上記のtickのコードで使われているgetについてですが、getって get = State $ \s -> (s,s) って定義されてますよね。 じゃあ n <- getのnには \s -> (s,s)っていう関数が束縛されてるんじゃないでしょうか? でも次のputでは数値として使われてるから、nは数値なんだろうけど、 どうしてそうなるのかわからないです。
>>840 do式で使われる<-は左辺を右辺に束縛する訳じゃない。
do
n <- get
put (n + 1)
は、
get >>= (\n -> put (n + 1))
の略記。
>840 get に限らず State はそもそも関数みたいなものだと思ってくれ。 「State s a」というのは、大雑把に言えば s -> (a, s) という型の関数。 そして、State モナドの束縛も一種の関数合成と考える。ただし、ふつうの (.) とかと違うのは返り値の型が (a, s) のように分かれているという点。な ので平常時は a 型の方だけが渡されていって、 s の方は無視する(変更しな い)ように合成している。 以上をふまえて、その tick という値は、 (\s -> let (n, s') = get s in (\s -> let (_, s'') = put (n+1) in (n, s'')) s') みたいな関数だと考えられる。 すると get と put の定義から、 (\s -> let (n, s') = (s, s) in (\s -> let (_, s'') = ((), n+1) in (n, s'')) s') となり、うまく行っているのがわかると思う。
843 :
840 :2006/10/19(木) 23:25:39
>>841 ,
>>842 >get に限らず State はそもそも関数みたいなものだと思ってくれ。
>「State s a」というのは、大雑把に言えば s -> (a, s) という型の関数。
これはnewtype宣言のことを言ってるって思っていいんでしょうか。
>そして、State モナドの束縛も一種の関数合成と考える。ただし、ふつうの
>(.) とかと違うのは返り値の型が (a, s) のように分かれているという点。な
>ので平常時は a 型の方だけが渡されていって、 s の方は無視する(変更しな
>い)ように合成している。
例えば、getContentsはIO::Stringじゃないですか。で、
do
cs <- getContents
print cs
見たいにつかうじゃないですか。というわけで、
左辺 <- 右辺
は右辺のモナドの印(上の例でいればIO)が外れてただの値になり、
左辺に入る、という理解をしていました。その考え方でいくと
Stateの印が外れた関数(runState)が左辺に入る。で良いとおもっていたのですが・・・
なんでa型の値だけが左辺に渡されるのでしょう??
それと「平常時」ってのが気になるんですが、平常じゃない場合もある・・・?
どうも Java歴数ヶ月のデザインパターンも把握してないunkoです Haskellが世界最強プログラミングコンテスト(?)みたいので いつも1位だって聞いてここきました で、偉大なハッカーはPerlとかLispなんかを愛用してるみたいですが その点Haskellはどうですか? 2chの住民的な意見を期待してる
>は右辺のモナドの印(上の例でいればIO)が外れてただの値になり、 型の話とデータの話を混同してないか。 型について言えば、<-の左辺の型は、右辺の型からモナドを外したものになる、と言うのは正しい。 getContentsならIO Stringに対してIOを外したStringだし、 getならState s sに対してState sを外したsだ。 データについて言うと、右辺から左辺を取り出している訳ではまったくない。 getContentsは標準入力を読むという動作、getは単なる関数をラップしたものであって、 そこにStringやs型の値を内包している訳ではない。
>>844 Haskellが活躍してたのは去年まで。
今年は見る影も無い。
問題の特質を見抜いて、適切な道具を選ぶのが偉大なハッカー。
特定のツールに固執するのは間違い。
>>846 あれ?
今年はGoogleの社員チームが1位になったんだよね?
その中にHaskell使ってる人いなかった?
>>847 今回のコンテスト・・・というか、ゲームの内容見た?
今回の内容じゃあ言語の優劣は出ないよ。
Haskell使ってる人が居ても、ただそれに慣れてるってだけさ。
>843 「平常時」から外れるのは実際に状態を操作する系の処理、ようするに get、 put、modifyなどのことを想定して書いた。 あとは 845 の言うとおりかなぁ。 型について言うと、 instance Monad IO だから、 IO String から IO がはず れて String になる。 同じように、 State では instance Monad (State s) だから、 State Int Int に対しては State Int がはずれて Int が出てくるわけだ。
850 :
838 :2006/10/20(金) 03:34:58
>> 839 Win2K, GHC6.6でssc-0.0.10を試してみました。 cp65001で837のコードを動かしたら、 諸行無常のHELLO WORLD LO WORLD という表示になりました。 なんでLO WORLDがくっつくんだろう。 あと、リダイレクトさせた場合はやっぱりShift JISになるみたいです。
>>850 >という表示になりました。
これはWin32 APIのWriteFileが実際に出力したバイト数よりも小さい値を戻すのが原因です。
OSの問題なわけですが、どうしても必要なら対策を考えます。
>あと、リダイレクトさせた場合はやっぱりShift JISになるみたいです。
これは意図した動作です。標準入出力がリダイレクトされた場合、コンソール入出力ではないので、
システムのコードページにしたがってコード変換します。
>>851 >これはWin32 APIのWriteFileが実際に出力したバイト数よりも小さい値を戻すのが原因です。
こんなすごいバグがあるんだ。10年以上 Windows でプログラム書いてるけど
経験したことも聞いたこともありませんでした。
UTF-8で"諸行無常のHELLO WORLD"をコンソールに WriteFile すれば再現可能ですか?
>>852 私の環境(WinXP SP2 日本語版)では再現できます。chcp 65001した状態で、
下記のコードを実行すると、4/8 writtenと表示されますが、実際には8バイト全て出力されています。
# include <windows.h>
# include <stdio.h>
int main(void)
{
const char *msg = "\xe8\xab\xb8\xe8\xa1\x8c\r\n";
DWORD written;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msg, strlen(msg), &written, NULL);
fprintf(stderr, "%d/%d written\n", (int)written, (int)strlen(msg));
}
すれ違い御容赦。
UTF-8で 日本語 と表示されるようなプログラム main = putStrLn "\230\151\165\230\156\172\232\170\158" をTrueTypeFontで表示しているcmd.exe上でコードページ65001のもとで 実行するとpermission deniedになるんですが、 それもこれに関連したバグなんでしょうか?
>>853 実行してみると、妙な記号と 8/8 writtenと表示されました。
コンソールのプロパティを調べると、フォントが「ラスタ フォント」になっている。
他にもう1つだけ選択可能な Lucida Console フォントに変更してみると、4/8 writtenとなって
再現しマスタ。
というか漏れのPCだと、そもそもCP65001 で日本語フォント使えないっぽいw
>>855 chcp 65001する前にフォントをMSゴシックに変えればOK
興味もったからこれからインストールしてハローワールドくらいやってみようと思う ちなみにJava歴5ヶ月のプログラマ初心者です なにか注意点ある? 心構えとか
858 :
デフォルトの名無しさん :2006/10/21(土) 02:02:16
age
Javaより簡単ですよ。たぶん。
860 :
デフォルトの名無しさん :2006/10/21(土) 03:46:51
型エラーは慣れの問題です
doがdoじゃないこと returnがreturnじゃないこと
Monadを難しく考えるな、感じるんだ
Stateモナドの説明とか見たけどここの人って難しいことを難しくしか説明できないのね
>>847 1位と3位がgoogleチームで1位のチームはC++とHaskell、2Dが使用言語だね
>>848 VM作成なんてHaskellとかのお家芸みたいなものじゃないかと
初心者の俺にわかるように、いかにハスケルがVM作成に向いてるかという "かんたんな"説明してくれ
アホは相手にしないという斬新なスタイルを採用
>>865 >VM作成なんてHaskellとかのお家芸みたいなものじゃないかと
冗談じゃない。よほどチューニングに慣れたHaskell使いじゃないと
まともな速度で動くVMを短時間では作れないだろう。
Haskell有利な点があったとすれば、パズルを解くような補助プログラムを
書きやすいということだと思う。
>>867 具体例も挙げれないんじゃおまえもアホに含まれる
vm はどうか知らないが言語の仮実装には向いているかもな Perl6 の Haskell での実装である Pugs は恐ろしく短期間で出来上がったらしいし
visual haskell便利やなぁ。
なんすかそれ
型情報バリバリ使ってバリバリ補完とか、 ツールチップでリファレンス表示とか、 書いてるそばからエラー指摘&補正案提示とか、 そういう開発環境出て来ないんかなぁ。
>>870 関係ありまくりだって。
たとえば black の 1000 点を受理させるとか、
adventure でオートパイロット走らせるとかするには
それなりにスピードがでないと困る。
BASICコードのコンパイルに半日掛けましたが何か?
>>878 ゲーム内で出てくる変態言語の一つ。
いくつかの基本素子を二次元平面上に配置・配線することで
プログラムを(ASCII Artで)表現することができる。
自分の中で自分に結線することができたりするなど、
細かい部分で関数型言語の香りが感じられる言語。
ゲーム内にはこの言語のインタプリタが入っており、
ペアノ算術やリストの反転、レイトレをイメージした漸化式を解く
プログラムなどを作成することになる。
( ´_ゝ`)フーン
大文字でも小文字でもないから、という間抜けな理由で 漢字や仮名を識別子に使えないのはどうなんだろう。
いや、Haskell作ってるの日本人じゃないから
いや、それは分かってるが。 ギリシャ文字やキリル文字や、さらには全角空白まで認められてる言語仕様なのに、 漢字や仮名が使えないのは片手落ちっぽいな、と思っただけ。
はぁ?
インストールの仕方がわかんねーーーー おしえろおまえら
環境と、何をインストールしようとしているのか書け。
Windows XP sp2 Hugs
そんなURLは最初から知ってるんだよ。。。 WinHugs-Sep2006.exe(14MB)だけインストールすれば使えんの? だとすれば hugs98とSep2006.tar.gz(5.3MB) ってなに? あと、MinGWとかいらないの? (↑これがなんなのかよく知らないが)
>WinHugs-Sep2006.exe(14MB)だけインストールすれば使えんの? うん。 >だとすれば hugs98とSep2006.tar.gz(5.3MB) ってなに? ソースコード >あと、MinGWとかいらないの? いらない。
WinGHCi みたいなのがあるといいんだがな。 WinHugsをいじって作れるかどうか、ちょっとソース調べてみるか。
module Qsort where qsort _ [] = [] qsort f (x:xs) = before ++ (x : after) where before = qsort f $ filter (not . (f x)) xs after = qsort f $ filter (f x) xs これを実行しようとしたら ERROR file:.\Qsort.hs:5 - Syntax error in input (unexpected `=') なにが悪いんですか
>>894 インデントがおかしい。
afterのカラム位置をbeforeと揃えるべし。
インデントを直してみたら Undefined variable "s" とかでて、適当にスペースを直したら Undefined variable "a" になった その変数は定義されてませんとかいうけど そんな変数作ってません><
俺のところでは通るんだが。 module Qsort where qsort _ [] = [] qsort f (x:xs) = before ++ (x : after) where before = qsort f $ filter (not . (f x)) xs after = qsort f $ filter (f x) xs これをコピペしてもだめ?
あーできてた Qsort> qsort (<) [8,3,5,2,7,1,9] っていうように引数?を指定してないだけだった 勝手が違うから全然わかりましぇん
微妙にわかってきた いまのところの感想だと、数学の公式勉強するための言語って感じ ところで今までは.hsファイルを直接開いて(WinHugsに関連づけて)やってたんだけど 直接WinHugsを起動したときに hugs> から始まるけど、どうやってファイルを指定すればいいの?
もう少し工夫してこんなのは? qsortBy _ []=[] qsortBy f (x:xs)=impl id++x:impl not where impl g=qsortBy f $ filter (g.f x) xs qsort::Ord a=>[a]->[a] qsort=qsortBy (>) beforeとafterをまとめてみた。
>>901 そこまでアホじゃない・・・
パス名の指定はどうすんの?
まさか全ドライブから自動検索なんてしないよね?
コマンドで人と会話するな! 日本語を使えよ
ホントこのスレばかばっか 偏差値しかなさそうだな
>>902 絶対パスでも、カレントディレクトリからの相対パスでも良い。
ねーねー 大学もでてない以前に高校で物理すら習ってない俺には クイックソートすら何かいてるんだが意味不明なんだが だれか記号の意味おしえて
>>907 Haskellや類似の言語を一つも知らないなら意味が分からないのは当然。
入門書でも読んでみたらどうよ。
うせろ
高速とか実用性はともかく言語仕様ほぼ変わらないっていうのはどういうレベルの話なんだ?
みため
そのふたつの言語仕様がほぼ変わらないなら、C#とJavaはほとんどいっしょってことになるだろうなぁ
>>912 副作用に対するアプローチが違うだけじゃん
仕様見るのめんどくさいんだけど、IOモナドってあるの?
IOモナドよりも高速なものが実装されてる
高速なものよりも、使いやすくて一貫性があるものの方がいいな。 条件満たしてる?
922 :
デフォルトの名無しさん :2006/10/28(土) 11:37:42
どれもたいした違いじゃないだろ
たいした違いかどうかは人による。 初代とSEEDを同じガンダム扱いされたら、お前だって嫌だろ?
そこまでの違いはねーよwww 遅延評価や参照透明性などの基本的な考え、型の概念などもほぼそのまま使える コンセプトとしてかなり同根のものだろ 記述も基本的なところ以外はほとんど差もなし Haskell 使えるヤツなら脳コストも少なく楽に移行できるだろう Monad も言語で保証されて居るものではないのでその概念を持っていくことは普通に出来る で、IDE で環境を配布して C++ 並みに高速と来れば使わない手はない まぁまだ環境が整っていないってのはあるがw あれだ、人が増えればそれなりに環境も整うからおまいらもっと使ってやってくださいお願いします
GHCで、ある関数をn回実行する時間を計測する、便利な方法はありますか?
Prelude> -- product [1..10000]を十回求めてみる Prelude> :set +s Prelude> foldr seq () $ map (\_ -> product [1..10000]) [1..10] () (7.23 secs, 878865620 bytes) GHCiだとこんな感じか。
なるほど。どうもです。 ghcでコンパイルした場合と似たような速度になるんですかね。ひとまずやってみます。
Fedoraのextraに含まれているghcでは、ghc -prof はできないのだなぁ。 残念。 Failed to load interface for `Prelude' とか言われてしまう。
>>931 できそうです。
ありがとうございました。
函手ってなんですか?
Maclane嫁
マックレーンて難しすぎない?俺わかんねー
マックレーン読みながらHaskellやっているやつなんているわけねぇだろ。
数学屋は脳みそ普通じゃないから(尊敬の意)
その割には圏論的なHaskellとやらの解説が少ない気がするんだけれど・・・。 どっか簡単に導入ってサイト作っている人いないのかね。 これだけ圏論だHaskellだって騒いでいたのに正直なんの関連性があるのかよくわからん。
>>937 っていうかすでにConceptual Mathematicsじゃないのね・・・。
>>939 言語の各機能について圏論的に説明したって面白いことはあまり無いと思う。
この分野で圏論が強いのは、関数型言語が圏論的に綺麗な構造を
しているのでプログラムの性質がしらべやすくなっている、ってだけ。
たとえばリストでは map は f: A → B を函手で写したもの、
fold, unfold は代数の始対象, 終対象から一意に定まる射、
などと特徴付けられ、いろんな性質が直ちにわかったりする。
> プログラムの性質がしらべやすくなっている、ってだけ。 というよりも、圏論的なのは処理系実装上の問題であって、圏論云々は一般プログラマが気にすべき話じゃないよね。
>>943 俺の考えでは、そもそも素晴らしい関数型言語の世界があって
現実の言語処理系はそれをどれだけ綺麗に書けるか、という感じ。
だから、書きやすさを度外視すれば C++ で圏論に基づくプログラム
を書くこともできて、実際 Google の MapReduce はそうなっている。
Google の中の人が一般プログラマかはあやしいと思うけど、
気にすべき話じゃないってのは何か違うなあと思う。
945 :
デフォルトの名無しさん :2006/11/02(木) 17:38:32
すみません、質問させてください。 関数の途中で結果を出力させたいのですが、 ↓このようなことはできますか? 「print p」の型はIO ()ですが、それを さっと気軽に埋め込めるといいんですが・・ fun1 :: Int -> Int fun1 n = let p = n * 3 in print p p + 1
Debug.Trace.trace か unsafePerformIO を使え
>>942 >>fold, unfold は代数の始対象, 終対象から一意に定まる射、
詳しく。代数の始対象、終対象ってなに?
アイディアだけでもっていうかアイディアだけくれ。
というか圏論と代数のつながりがイマイチわからん、普遍射とかはわかるんだけれど。
準同型射で類別したもの=代数
くらいの認識です。
ちなみにね。
圏論とほんとに相性がいいのはtotalな関数型言語。 Haskellにはどうしても_|_がつきまとうのですっきりいかない。 coproductの扱いとか。
950 :
942 :2006/11/02(木) 21:47:43
長文ごめんよ。
>>947 代数:
http://en.wikipedia.org/wiki/F-algebra 始対象:
http://en.wikipedia.org/wiki/Initial_object あたりを前提として説明する。分からなければ再度聞いてくれ。
以後、扱う圏 C はすべての型からなる圏とする。
関数型言語でよく出てくる型は再帰型というもので、たとえば
data List = Nil | Cons A List
みたいに再帰的に定義される。こう定義された List というのは
数学的には 函手 T = 1 + A×I の不動点で定めたことになる。
ここで 1 は 一点だけからなる型への定函手、A は型 A への定函手、
I は恒等函手、+ は直和、×は直積。
関数型言語で考えている圏では、こういう函手の不動点の存在を示すことが
でき、しかもその不動点が代数の始対象になることが証明できる。
たとえば T = 1 + A×I でやってみると、不動点は
1 + A×1 + A×A×1 + ... なる型で、すなわち加算無限個の
A の要素からなる型、つまり A のリストになる。これを L と書く。
h: T L → L は何かというと L が T の不動点だから h: T L = L なる同型
があって、具体的には h Nil = Nil, h (a,as) = (a:as) がそうなる。
951 :
942 :2006/11/02(木) 21:49:35
つづきごめんよ。
>>947 (L,h) は始対象なのだから任意の (X,f) に対して一意に
g: (L,h) → (X,f) が存在して、g . h = f . L g が成立する。
この両辺に (a,as) を食わせてみる。L g = id + id×g に注意すると
左辺 = g (h (a,as)) = g (a:as)
右辺 = f (L g (a,as)) = f (a, g as)
つまり g (a:as) = f (a, g as)。カリー化されているけど、これはまさに
g = fold f をあらわしていて、fold が自然に導入される射だということがわかる。
また、ここまでの議論の双対をとると unfold が同様にあらわれる。
もとの函手として T = 1 + A×I×I でやると全く同じように
二分木の上での fold やら unfold が出てくるし、もっと複雑な
データ構造の上でも同様に議論できたりする。
952 :
947 :2006/11/02(木) 21:59:27
thx!!!!!! ちょっと理解するまでに時間かかるけどとりあえずカキコ 明日あたり質問するかも。 にしても函手のそういう使い方は知らんかった。 単なる「カテゴリ間のモルフィズム」程度の認識しかなかったけどそういう風に論理展開できるのね。 っていうか圏論の基礎にそんなこと載ってたっけ? まぁ、圏、函手、普遍射、随伴、自然変換、モナドの部分くらいしか読んでいないんだけどね・・・。
だからおまいらbottomを無視するなって…これだから数学者は(ry
なんかすごいなー。
>>953 諦めろ。数学者のアタマに停止しない計算は存在しない。
956 :
947 :2006/11/02(木) 22:10:10
すまん、早速質問というか確認。 >I は恒等函手、+ は直和、×は直積。 直積Xって積圏作る函手でしょ。 直和+ってアーベリアンな積圏作る函手ってこと?
957 :
947 :2006/11/02(木) 22:23:20
あっ。F-algebraってそういう意味か。 そんなの知らないよ。orz F-algebraは既知じゃないです。orz
958 :
942 :2006/11/02(木) 22:30:53
>>956 分離和 (separated sum) といったほうが良かったかも。
C の対象 A, B について A+B であらわされる対象は A の要素と
B の要素の集まり。共通する要素はラベル付けして区別しておく。
f :: A -> A', g :: B -> B' について f+g :: A+B -> A'+B' は
x ∈ A+B が A に属する要素なら f, B に属する要素なら g を
適用するようなもの。
>>957 何らかの自然っぽい構造を持ったものはだいたい代数と言ってしまうので
ミスリーディングではあるんだけどね。
959 :
947 :2006/11/02(木) 22:43:48
>>958 >>分離和 (separated sum) といったほうが良かったかも。
初耳です。orz
そして圏論の基礎にも載っていない。
958さんは何の本を読んでいるのですか?
自分は圏論の基礎以外持ってないっす。
Haskellは学術雑誌とかで活発に議論されてるんだろうなあ。英文で。 自分は和書でも読むのが遅いのに英文だと輪をかけて遅くなるし… 少しは慣れないと。
961 :
947 :2006/11/02(木) 22:48:58
×958さんは何の本を読んでいるのですか? ○942さんは何の本を読んでいるのですか?
いきなり低レベルな話わりこんで すまんす。 data HogeFuga = Hoge String | Fuga String hogeList = [Fuga "", Hoge "aaa",Fuga "bbb"] ってデータ定義とリストがあって Hogeをリストから検索したいとき findHoge = find isHoge hogeList where isHoge flg = case flg of {(Hoge _) -> True; _ -> False} ってなかんじで書いてみたけど どうにも case 式がダサイというか冗長なかんじ。 なんかスマートに書ける関数とかイディオムとか ないですかね。 (某言語の instanceof みたいな)
こういうのを見るたびに、Template Haskellがもっと使い易い構文だったらと思うよ。 こういうちょっとしたマクロの需要は確かにあるはすだけど、 いちいち$(testConstr [| Hoge |])なんて書いてたら冗長過ぎて略記法にならない。
>>962 isHoge (Hoge _) = True
isHoge _ = False
って書くのが普通じゃないの
966 :
962 :2006/11/04(土) 10:51:50
>>963 ないっすか。(´・ω・`)
>>964 テンプレートハスケル?
なんか藪から蛇が!?
>>965 まあ、元の書き方よりは大分短いのでこれで
よしとすべきですかね
こうするとListを入れなくてすむよ findHoge = head (filter isHoge hoge) where isHoge (Hoge _) = True isHoge _ = False データ構造がそのままならパターンマッチしか無いけど 変えていいならこう data HogeFuga = Hoge | Fuga hogeList = [(Fuga, ""), (Hoge, "aaa"), (Fuga, "bbb")] findHoge = lookup Hoge hogeList
決してお薦めはしないけど、「スマートに書ける関数」なら一応ある。 {-# OPTIONS_GHC -fglasgow-exts #-} import GHC.Exts import Data.List sameConstr :: a -> a -> Bool sameConstr x y = dataToTag# x ==# dataToTag# y findHoge = find (sameConstr Hoge{}) hogeList data HogeFuga = Hoge String | Fuga String deriving (Show) hogeList = [Fuga "", Hoge "aaa", Fuga "bbb"]
>>959 「圏論の基礎」の原題を三回読んで,改めて本を探すべし.
ちなみに僕には Barr-Wells の本が判りやすかった.
>>958 > 何らかの自然っぽい構造を持ったものはだいたい代数と言ってしまうので
> ミスリーディングではあるんだけどね。
数学の側の感覚でいうと,作用(素)のつくる代数というものに相当するんじゃないかと思う.
970 :
942 :2006/11/04(土) 21:48:06
971 :
942 :2006/11/04(土) 21:49:02
972 :
962 :2006/11/04(土) 22:39:54
>より抽象化された記述からcを吐き出す言語があると聞いて
これは間違っていないけど、たぶん誤解している。
Haskellは、抽象化された記述をもとにコンパイル時計算をして
最適なコードを出力するような方向性の言語ではない。
むしろ、抽象化の解決は実行時に行われることが多い。
GHCには強力な最適化器があるので、これをなだめすかして
効率的なコードを吐かせることも不可能じゃないが。
>データ構造の指定みたいなのできるの?
意味が分からん。生のバイト列を扱えるかどうかという疑問なら、扱える。
>計算速度はcのプログラムと比べて我慢できるLvなの?
何を、どのように、どれくらいまじめに書くかによる。
Computer Language Shootout BenchmarksでのHaskellとCの比較。
http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=ghc&lang2=gcc
975 :
947 :2006/11/05(日) 23:42:06
>>969 >「圏論の基礎」の原題を三回読んで,改めて本を探すべし.
>ちなみに僕には Barr-Wells の本が判りやすかった.
ども!ありがとうございます。
3回ですか。正直、圏論敵考えを展開するための土台部分が弱いので後半部分はきついです。普通の代数をもう少しやり直してみます。(たぶんそちらのほうが早道なので)
そのあとにBar-Wellsを見てみます。(できたら)
>>970 >分離和は集合の圏での普通の意味の直和と一致するから
>問題ないけどね。MacLane p.80 あたり参照。
ここら辺完璧すっ飛ばしてました。読んでみます。
>俺が読んだ本は多すぎて紹介しきれんけど、プログラミングを
>圏論的に解説したものとしては
>
http://db.cs.utwente.nl/Publications/PaperStore/db-utwente-404F4540.pdf ってのが読みやすかった。好みが分かれそうだけど。
ぱっとみですがこれ結構いいかも。薄いし全部印刷して一回読んで見ます。
ありがとうございます。
> 何らかの自然っぽい構造を持ったものはだいたい代数と言ってしまうので
> ミスリーディングではあるんだけどね。
環構造持っていれば代数。という感じじゃないんですかね。
わかってきたらまた質問するかもです。
そのときはよろしくお願いします。
>>975 三回読めってのは中身ではなく原題のことだろう。
「Categories for the Working Mathematician」
なので、基本的にあの本は数学屋向け。プログラム屋には向かない。
977 :
947 :2006/11/06(月) 00:24:18
関数言語を勉強するために必要な本と環境はみんなどうやって始めましたか? 何分馬鹿PGなもので関数言語はLispちょっとわかるぐらいの馬鹿です。
>>979 まじっすかできればその時参照したページなどを
次スレで追加していただけないでしょうか?
なんでこんなにスレのびた?
>>980 shiroさんのPractical Schemeの記事でも読んだら?
HaskellでなくSchemeで
しかも純粋な純粋な関数型の世界とはちょっと違うけど勉強になるよ
あとはnobsunさんのsampou.orgか
Haskellだけど記事が少ない
オセロとかのゲームを作ってみれば? 簡単に作れて、工夫することで言語仕様の理解が深まる教材だと思う。
>>983 それスレ立ててレクチャーしてくれよ
【Haskell】1がオセロゲーム教えるスレ
このスレは1が延々と、Haskell言語を使いオセロゲームの作り方について
詳しく丁寧に説明していくスレです。
Haskellの言語仕様の理解を深めるのに最適な教材です
>>984 逆だろw
【Haskell】1がオセロゲームを作るスレ
オセロって言っても、要は探索効率や学習効率の問題なんだけどね。 いくらでも工夫の余地はある。
急にスレが止まった めんどくさがらずに教えろゴラァ!
まずは次スレを立てるこった
一ヶ月でHaskellを鍛えたい って考えたときどの資料みればいいの?
Yet Another Haskell Tutorial なんてどうよ
993 :
2 :2006/11/07(火) 18:38:38
せんとりがっせんいくぞごらぁー(AA略
あらいぐまハスケル あらいぐまハスケル あらいぐまハスケル
∧,,∧ (;`・ω・) 。・゚・⌒) 今夜はハスケルです。オセロゲーム作るよ!! / o━ヽニニフ)) しー-J アッ! 。・゚・ ∧,,∧ て 。・゚・。・゚・ (; ´゚ω゚)て // / o━ヽニニフ しー-J 彡 ∧,,∧ ショボーン ( ´・ω・) c(,_U_U ・゚・。・ ゚・。・゚・ 。・゚・ ━ヽニニフ よしバレてない クルッ ∧,,∧ ミ(・ω・´ )つ サッサ c( U・ ゚U。彡・ 。・゚・ ━ヽニニフ ∧,,∧ 。・。゚・。 ゚・。゚・ モナド〜 ( ´・ω・)つ\・゚・ 。・゚・・/
ハ、ハ、スー ケル ♪ \ハスケッ、ススン、ハ、ケルッ/ ♪ ('A`) ♪ _ ノ )>_ キュッキュ♪ /.◎。/◎。/| | ̄ ̄ ̄ ̄ ̄|
┌┐ ●●● 人 ││ ●\ ●\ ノ二\ ナ ゝゝ V ●●● ●\ ●\ / / 乙 つ O ●\ ●\ ●\ ●\ ●●● ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●\ ●●● \ ●\ ●\ ●\ ●\ ●\ \\\ ●\ ●\ ●\ ●●● \ ●\ ●\ ●\ \\\ ●\ ●●● \ ┌┐ ┌┐ ●\ \\\ ┣━┳┃┃ ┃ ││ ││ ●●●\ ┃ ┃┃┃ ┣┓ ━╋ ━╋ V V \\\\ ┛ ━┛ ┃ ┏┫ ┏┫ O O /■\ ) (´⌒(´ ⊂(゚Д゚⊂⌒`つ≡≡≡(´⌒;;;≡≡≡ ズザーーーーーッ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。