1 名前:デフォルトの名無しさん mailto:sage [2012/01/02(月) 22:19:28.26 ] haskell.org ttp://www.haskell.org/ 日本語サイト ttp://www.sampou.org/cgi-bin/haskell.cgi ttp://www.shido.info/hs/ 過去ログ 関数型プログラミング言語Haskell Part1 ttp://pc.2ch.net/tech/kako/996/996131288.html Part2 ttp://pc2.2ch.net/test/read.cgi/tech/1013846140/ Part3 ttp://pc8.2ch.net/test/read.cgi/tech/1076418993/ Part4 ttp://pc8.2ch.net/test/read.cgi/tech/1140717775/ Part5 ttp://pc8.2ch.net/test/read.cgi/tech/1149263630/ Part6 ttp://pc11.2ch.net/test/read.cgi/tech/1162902266/ Part7 ttp://pc11.2ch.net/test/read.cgi/tech/1174211797/ Part8 ttp://pc11.2ch.net/test/read.cgi/tech/1193743693/ Part9 ttp://pc11.2ch.net/test/read.cgi/tech/1211010089/ Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/ Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/ Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/ Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/ Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/ Part15 ttp://hibari.2ch.net/test/read.cgi/tech/1310199414/ Part16 ttp://toro.2ch.net/test/read.cgi/tech/1317958045/
267 名前:デフォルトの名無しさん mailto:sage [2012/01/17(火) 19:06:57.29 ] >>266 初め付けられなかったから訊いたみたんだが、 今再挑戦したらあっさりできた どうもレイアウトルールに従ってなかったみたいだ where {-# INLINE f #-} f x = ・・・ なんてのはできないのね where {-# INLINE f #-} f x = ・・・ これならできた ちょっと不格好になるが仕方がない 助かった、ありがと
268 名前:デフォルトの名無しさん mailto:sage [2012/01/19(木) 01:16:44.99 ] 東京にある6つのキー局の内、製作から財務まで一貫して朝鮮人が行ってるテレビ局が1つ 中国共産党から毎年大量の反日工作費が流れているテレビ局が2つ もろに北朝鮮と繋がっているテレビ局が1つ 年寄はまだまだテレビという外国人に騙され続ける
269 名前:デフォルトの名無しさん mailto:sage [2012/01/19(木) 22:41:54.05 ] Float型やDouble型などの、負方向の最大値(無限大ではない)や、 最もゼロに近い正の数などを得る方法は何かないでしょうか
270 名前:デフォルトの名無しさん mailto:sage [2012/01/19(木) 23:40:17.17 ] >>269 Hugs> 1/0::Float inf Hugs> -1/0::Float -inf Hugs> 1/(1/0)::Float 0.0 Hugs> -1/(1/0)::Float -0.0
271 名前:デフォルトの名無しさん mailto:sage [2012/01/19(木) 23:44:42.25 ] import Numeric.IEEE -maxFinite succIEEE 0
272 名前:デフォルトの名無しさん mailto:sage [2012/01/19(木) 23:45:01.08 ] >>270 >>269 でも言いましたが、無限大ではないです 「計算が可能な」負方向の最大値、正方向の最大値です あと、最もゼロに近い正の数です
273 名前:デフォルトの名無しさん mailto:sage [2012/01/19(木) 23:51:23.95 ] クラッシュするんじゃ
274 名前:デフォルトの名無しさん mailto:sage [2012/01/20(金) 00:02:03.11 ] >>271 ieee754 パッケージを使うのでしょうか インストールして、ghci 上で使ってみましたが、 m というモジュールが見つからないというエラーが発生します 今までの経験から察するに、MinGW 用の libm.dll という dll が必要ではないかと思いますが、合ってますか? gnuwin32.sourceforge.net/packages/libm.htm ここから辿れるページで探しているのですが、なかなか見つかりません 今日はもう遅いので後日探してみます
275 名前:デフォルトの名無しさん mailto:sage [2012/01/20(金) 00:10:16.65 ] >>271 ごめんなさい、環境を書き忘れていました Windows7 GHC 7.2.2
276 名前:デフォルトの名無しさん [2012/01/20(金) 16:12:27.09 ] 「ふつうのHaskellプログラミング」ってどうですか?評判がいいですが、結構古いので ほかのにしようかまよってます。
277 名前:デフォルトの名無しさん mailto:sage [2012/01/20(金) 16:58:44.68 ] >>276 一度手続き型言語を修得した人向けで、読後、読み返しにくい と言うか、今はプログラミングHaskell一択だろう
278 名前:デフォルトの名無しさん mailto:sage [2012/01/20(金) 17:00:08.41 ] ちょっとでも英語読めるならlearn you(ryが初心者向けとしてはベスト
279 名前:デフォルトの名無しさん [2012/01/20(金) 17:17:06.71 ] マセマティカのように log 6 - log 2 を 誤差なしにlog 3 ときっちり答えてくれるようなライブラリありませんか?
280 名前:デフォルトの名無しさん mailto:sage [2012/01/20(金) 19:56:42.13 ] >>279 logfloat パッケージというものがあるみたいだ 使ったことがないから(インストールする気もない)分からんが、 LogFloat というデータ型で log x を表現するっぽいから、 もしかしたら LogFloat 6 - LogFloat 2 = LogFloat 3 となるかも知れん
281 名前:デフォルトの名無しさん mailto:sage [2012/01/20(金) 19:59:20.97 ] >>280 すまん、紛らわしい間違いをしたな もしかしたら、logFloat 6 - logFloat 2 == logFloat 3 となるかも知れん
282 名前:デフォルトの名無しさん mailto:sage [2012/01/21(土) 01:24:19.13 ] Learn You a Haskell はもうすぐ翻訳版が出るんだっけ? まあ英語ならただで読めるんだけど
283 名前:デフォルトの名無しさん mailto:sage [2012/01/21(土) 06:03:22.00 ] >>276 「ふつうの」は、実際に役に立つプログラムを書きながら Haskell を学ぶという 立場で、その方針はよいと思う。誤植も少ない。古いことは気にしなくていいと 思う。 ただし文法の説明はかなりはしょってあるし、網羅的でもない。モナドの説明は (まちがってはいないが)ごく簡単で、あれじゃわからないだろうと思う。 Wiki の作りかたの話は、省略した部分が多すぎて、本を読んだだけではさっぱり わからなかった。
284 名前:デフォルトの名無しさん mailto:sage [2012/01/21(土) 09:54:12.35 ] Haskellerがtailコマンドを実装すると ファイルを全部読み込むクソコードを書くと 教えてくれる良書 > ふつける
285 名前:デフォルトの名無しさん mailto:sage [2012/01/21(土) 13:53:02.40 ] 【プログラミング部】 PHPが100倍速で動くようになったぞー awabi.2ch.net/test/read.cgi/poverty/1327050821/
286 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 11:23:48.95 ] >>284 > ファイルを全部読み込むクソコードを書く Haskellが綺麗に書けるって言ってるときは 大抵こんなのばかりだな
287 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 13:46:53.61 ] 数値リテラルの範囲をコンパイル時に指定できるGHC拡張はないでしょうか たとえば newtype NumPadKey = NPKey Integer -- 0 から 9 に限定したい let a = NPKey 8 -- ok b = NPKey 21 -- コンパイルエラー こういう事をしたい場合は、 0 から 9 までの 10 個の数値が入った NumPadKey 型の値を返す 10 個の関数(num0 :: NumKeyPad など)を作るなどするしかないでしょうか
288 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 14:19:09.91 ] TemplateHaskellというGHC拡張を使えばできるよ!
289 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 14:27:24.57 ] >>286 コード上は全部読み込んでるように見えて、遅延評価で必要な分しか読み込まれないわけですが・・・
290 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 14:29:48.48 ] >>289 headはそれでいけるけどtailだと全部読むよ
291 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 14:36:41.48 ] >>290 tail も弱頭部正規形の形までにしか評価されないんじゃないのか?
292 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 15:10:57.18 ] なるほど>>284 は真実だな >>289 >>291 は馬鹿すぎwww クソ遅せえコードまき散らすなよw
293 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 15:25:22.29 ] ハッシュテーブルが確率に依存するみたいに 遅延評価も木構造のバランスが取れている確率に依存するんだよな
294 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 15:45:23.45 ] >>291 UnixコマンドのtailはHaskellでいうlastみたいなもん
295 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 15:58:12.71 ] >>290 take 10 $ tail [1..]
296 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 16:06:01.08 ] >>295 tail"コマンド"だって書いてるだろアホか
297 名前:295 mailto:sage [2012/01/22(日) 16:08:14.13 ] ほんとだ、ごめん
298 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 16:37:21.25 ] >>292 俺(>>291 )も完全に Haskell の Data.List.tail 関数の事だと勘違いしてた 馬鹿すぎで申し訳ない
299 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 16:43:56.55 ] 何が問題になってるのか、よくわからん。 メモリに全部読みこむのは「ふつうのHaskell」が getContents を 使ってるからで、Haskell 自体の問題ではないよね。 速度の問題なら、後ろからシークしていくのでないかぎり、どうせ全部 読むんだから問題ないはず。これも Haskell とは無関係。
300 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 16:52:34.31 ] >>299 どうしてシーク禁止なんて前提にするんだい? そこを笑われているのに、わかってないんだなw
301 名前:デフォルトの名無しさん [2012/01/22(日) 16:54:23.14 ] もうちょっと冷静に議論したまえ
302 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 16:59:54.18 ] 処理速度や使用メモリ量を気にするなら、 Haskell でも結局のところやることは変わらないような気がする System.IO.hSeek で後ろから一バイトずつ戻りながら、改行コードで区切ってく 遅延評価がほとんど活かせず、手続きっぽい実装になるが、 これ以外に良い実装方法が思いつかん
303 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 17:14:45.72 ] そんなDQN本だったっけと思って自分も見返してみた p.50より引用 > tailコマンドの作りかたにもいろいろありますが、今回は次のような方針で実装しました。 > 1. 行のリストを逆順にする > 2. 先頭からn行を取る > 3. 取った部分リストをまた逆順にする 実際のコード、同ページのリスト2.9 > main = do cs <- getContents > putStr $ lastNLines 10 cs > lastNLines n cs = unlines $ takeLast n $ lines cs > takeLast n ss = reverse $ take n $ reverse ss ここまでに使った関数は putsStr, putStrLn, print, length, take, reverse, lines, unlines アクションが getContents 入門書の序盤のリスト処理の例題としてはこんなもんじゃないだろうかと思う ふつける擁護とかしても仕方ないので俺ならこう実装するってのがあれば見てみたい
304 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 17:17:14.40 ] コードのインデントが崩れたけど見逃して
305 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 17:26:38.48 ] >>303 そうだよね。 おそらく「ふつうの」のネタ元と思われる「Software Tools」(ソフトウェア作法、 Fortran 版)にも tail を作る演習問題があって、解答は書いてないけどランダム アクセスの話よりずっと前に出てくるので、頭から読むことが期待されていると思う。
306 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 17:26:50.51 ] >>290 そりゃ、reverse使ってるからな Haskellは、アルゴリズムを考えないと本当に遅いし、同じアルゴリズムなら、LLなんて比較にならないくらい早いコードが簡単に書ける (ただし、ghci/runghcではなく、ghcで実行ファイルになったときに限る)
307 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 17:34:33.10 ] >>306 じゃあ tail コマンドを実装するにはどういうアルゴリズムが良いんだろ という話に若干移りかけている
308 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 17:41:39.84 ] >>307 うーむ・・・ 自分もアルゴリズムにそんなに詳しくないんだけど、10行と言う縛り固定だったり、何行表示するかコマンド引数で取れるなら、last関数を複数回使ったほうが速そうではある (EOF見つけるまで関数適用の必要ないと推測)
309 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 18:18:22.72 ] こういうのもIterateeがもっと整備されてくれば過去の笑い話になるんだろうな。
310 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 20:17:33.21 ] 必要な行数だけバッファリングしといて、 EOFきたらバッファを全部出力するのが、 メモリ効率的に有利だろう。O(1)で済むので。 getContentsしたらO(n)になってしまう。 常に「指定した行数 >≒ ファイルの行数」ならどっちも同じだが。
311 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 20:35:54.39 ] 必要な行に辿りつくまでの計算量はどこへ行ったんだ
312 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 20:45:16.49 ] unsafePerformIO使っていいんなら、普通にファイルの後ろから読んでできるな。 使わんかったら無理っぽい。俺には無理。
313 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 20:46:42.49 ] 空間計算量だよ。 seek可能なら後ろから舐めることもできるが、 泥臭いコードになるからチュートリアル向けのコードじゃないな。
314 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 20:57:18.53 ] >>313 ああ、必要なメモリの量もO記法で表すのか。ごめん
315 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 20:58:16.55 ] seekが制限されると、他の言語でもパフォーマンス出せないと思うが。
316 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 21:06:37.77 ] そんなこといちいち書きこむなよ。
317 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 21:09:34.27 ] >>312 君の考えた方法で、unsafePerformIO はどこに使うの?
318 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 22:32:20.73 ] unsafePerformIOとかhSeekとか出てるんだから、ちょっと考えれば わからない? 大したコードじゃないよ。5行くらいで終わる。
319 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 23:01:59.53 ] >>310 空間計算量なら takeLast n xs = diff x (drop n xs) where diff xs [] = xs diff (x:xs) (y:ys) = diff xs ys みたいなの使えばgetContents使ってもO(1)で済むよ
320 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 23:04:16.00 ] >>318 unsafePerformIO って要らなくない?
321 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 23:08:59.31 ] unsafeでなくてはならない意味がわからないんですけど。
322 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 23:18:32.67 ] >>320 要らない。さっきようやく気づいた。 まだ、Haskellになれてないもので、、、 でも、Haskellっぽく遅延評価で取り出そうと思うと、 unsafe使わざるをえんね。 まぁ、それを意図してるんだろうけど。
323 名前:デフォルトの名無しさん mailto:sage [2012/01/22(日) 23:32:52.07 ] >>319 モナらないと無理。 getContentsの中身はunsafePerformIOなんで。
324 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 00:13:13.59 ] unix の tail コマンドなどを Haskell で実装する場合、 もし hSeek 使って逆から読み取ることをするとなると、 読み込むファイルが utf-8 とかだったらどうするの? 今試しに hSeek で戻りながら hGetChar で1文字ずつ取ろうとしたら、 戻るバイト数が分からんかった
325 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 00:14:23.33 ] あ、すまん バイナリモードで読み取れば良いのか
326 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 02:32:36.04 ] >>323 ghc7.0.2で試してみたけど最適化なしでも空間使用量は一定だったよ
327 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 07:08:50.63 ] >>323 getContentsの中身ってunsafeInterleaveIOじゃないの?
328 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 07:31:08.49 ] iterateeやcondoit使っときなさいって
329 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 10:13:37.62 ] tailをHaskellで実装する意義が判らん。 初学者でも出来るような事は、Cみたいな言語で充分じゃないの?
330 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 10:19:33.95 ] そういう台詞は実際にコード貼ってから言えよ 負け惜しみにしか見えん
331 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 11:02:10.67 ] 意外と人多いのね、ここ。 実際に役に立つプログラムにすることを考えると、tail コマンドって $ bzcat backup.bz2 | tail -10 みたいにパイプで使うことが多いから、結局頭から読む版も作る必要があるよ。 教科書でやるなら、素直に頭から読む版を紹介して、ランダムアクセス版は 練習問題にするのがいいだろうね。
332 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 11:21:41.80 ] >>329 HaskellでできることをわざわざCでやる必要がないだろ
333 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 11:52:08.14 ] わざわざ泥臭いことをやってはいけないという空気に従うのが逆に面倒だな
334 名前:デフォルトの名無しさん [2012/01/23(月) 14:22:10.66 ] 具体化できない奴がやたら抽象化にこだわるみたいな
335 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 19:22:03.97 ] >>334 そのできない具体化とやたら拘る抽象化の例を挙げてみて もしかして具体例もなく、なんとなく抽象的にレスしてるだけとか?
336 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 20:32:55.92 ] 盛り上がってきたね。 別にプログラムなんて好きなんで作ればいいんじゃない?
337 名前:デフォルトの名無しさん [2012/01/23(月) 21:10:58.12 ] >>335 読解力が爆発してますね >>333 へのレスです
338 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 21:30:27.63 ] >>309 イテレーティ解説サイト教えてください!(日本語の)
339 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 21:30:48.60 ] >>337 だからさ、お前が「〜みたいな」って自分で言ってるじゃん その抽象的な「みたいな」をもっと具体的に説明してくれよ じゃないと、それが >>333 の喩えにちゃんとなっているのか、 あるいは >>334 が勝手に喩えていると勘違いしてるだけで、 何も喩えられていないのか、判断に困るだろ
340 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 21:35:22.98 ] >>338 「iteratee haskell」で日本語サイトをググってみたか? たとえば d.hatena.ne.jp/mkotha/20111106/1320584724 こんなページがヒットしたんだが >>337 「具体化できない奴がやたら抽象化にこだわる」事がどういう事か、 自分でもあまりよく分かって(頭の中で整理できて)ないんだろ? だから、例えばこういう奴とか言って具体例が出てこないんだろ?
341 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 21:48:59.93 ] 抽象化にこだわってるかどうかは知らんが、 とにかく具体的なコード書く能力が無いのは事実だな 「シーク禁止じゃなければ速いtail書けるんだけど、でも泥臭くなるから……(ぶつぶつ」 とか言いながら実際にはシーク使ったコードは書けない、みたいな
342 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 21:55:46.74 ] case of で、あるマッチングと別のマッチングで全く同じ式を計算させたい場合、 どう式を書くのがより合理的なのでしょうか 例えば次のような感じです data T = A Char | B Bool | C Bool | D Int | E String f :: T -> Int f x = case x of A d -> g1 d B d -> g2 d C d -> g2 d otherwise -> 0 パターン B b とパターン C d の場合が同じ式になっています この例の場合、レスの文字数などの関係で g2 d というように関数を適用してますが、 実際は別の関数にするほどでもなく、それでいて短くもないような、 例えば let が2〜3行に in が1行程度の式だったりします 2つのパターンの場合に同じ式を計算する事を分かりやすく示したいのですが、 C言語の switch case のフォールスルーみたいには書けないですよね コピペのミスなどを防ぐには、この例のように関数にまとめて、 それを呼ぶだけの式にするくらいしか手はないでしょうか
343 名前:デフォルトの名無しさん [2012/01/23(月) 22:00:11.07 ] >>339 具体化=泥臭い=hSeekでシコシコ読み込む方法と、すでに出ていることから察するに、 恐らく>>333 へ文句言ってると受け取って、こっちの文意が伝わってないのかなと思った でも>>339 では喩えになっているかって言ってるもんな 何かトンデモないこと言ってしまったんだろうか たしかに>>334 は毒づきすぎたから、そこはごめんなさい 議論の邪魔して失礼しました
344 名前:デフォルトの名無しさん mailto:sage [2012/01/23(月) 22:13:40.06 ] 誰かhSeek でスマートに実装したtailください
345 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 07:56:12.73 ] >>333 言いたいことは分かるが、ある程度は仕方がない 数回経験すれば自然と分かることだが、 Haskellで泥臭くやると、C言語などで泥臭くやる場合以上に 面倒で、スパゲッティで分かりにくくなり、かつメンテが難しくなる Haskellで泥臭くやるということは、手続き的な、 つまり計算「順序」に過剰に縛られたプログラムを書くということ 順序に縛られているから計算が一本の長い紐になり、 それがソース上の関数群を複雑に縫い止める C言語などなら、そこから少しずつリファクタリングし、処理単位の小さくし、 縫い合わされた巨大な処理を細かくばらすことは良くある でもHaskellでは一度複雑に縫い止めた関数群を少しずつばらすのは容易ではない 計算順序を意識しすぎた為にそうなったのであり、その意識を変えなければ無理 考え方そのものを変えた場合、少しずつ修正するよりは全てやり直した方が早い そうすると、後で全てやり直すくらいなら、初めから意識を変えて、 計算順序に過剰に縛られないように作ることに意識が向くようになる 初心者のうちは「意識を変えなければならない」という事が面倒でたまらないが、 そのうち「わざわざ」泥臭いことをやってはいけないという意識は消えていく 自然と泥臭いことをしなくなる
346 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 11:09:18.39 ] >>345 333じゃないけど、それは自分の実感と全然違うな Haskellで手続き的なコードを書くのは良くやるけど、 Cでやるのに比べて面倒だと思うことはほとんどない 多次元のmutable配列とかがHaskellだと構文的にごちゃごちゃするくらい リファクタリングについては、なんでそんな結論に至ったのか理解に苦しむ 局所関数定義と高階関数を自在に使える時点でCとは比較にならない そもそも「計算順序を意識」するのを止めるだけで関数的に綺麗なアルゴリズムが出てくる訳でもない 時間O(1)のtailを実装するには結局seekするしかないんだよ
347 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 12:11:52.41 ] だれかHaskellのスパゲティ屋さんのプログラム見せて
348 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 12:33:17.39 ] >>347 >>46
349 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 12:34:10.82 ] >>346 「計算順序を意識」とは言っていない 「計算順序を意識しすぎる」や「計算順序に過剰に縛られた」と言っている 意識しなければ正しい計算ができない事は承知している
350 名前:349 mailto:sage [2012/01/24(火) 12:49:06.27 ] それと > 時間O(1)のtailを実装するには結局seekするしかないんだよ 分かっている だから私はtailの時間O(1)の実装には一言も触れていない >>345 では、わざわざ泥臭いことをやってはいけないという空気になりがちな 私なりの理由を述べた(tailの実装といった具体的な対象ではなく一般論) やってはいけないとは言いすぎだと思うが、アプリの設計開始時から、 または Haskell によるプログラム開始時から 泥臭いことをやってはいけないというくらいの考えでプログラムした方がいいと思う 少なくとも Haskell では 泥臭い事を考えるのは、そうしなければ目標を達成する術が残っていない場合だけ 本当に最後の最後に考える最終手段くらいのもの 本来はもっと抽象度を高める方向に意識を向けた方が良いと思う 例えば seek で1バイトずつ取得したものを文字と解釈して計算するよりも、 getContentsに任せて「ファイルの内容を計算対象にする」方が抽象度は高い 蛇足かも知れんが、ついでに言えば入門書も抽象度を高める考え方や方法を伝授すべきだと思う
351 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 14:10:06.15 ] >>350 お前がそういう意見なのは全然構わん >>345 が「Haskellは泥臭いことをやるのには向かない」と 言っているように読めたので反論しただけ 個人的には泥臭いのを嫌がっていては実用コードは書けないと思っているから
352 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 15:21:05.01 ] >>348 TX クラクラ来た。
353 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 15:36:49.63 ] >>350 >本当に最後の最後に考える最終手段くらいのもの 最初でも最後でもどっちでもいいんじゃないの なぜ順序を決めたがるのか
354 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 16:01:49.74 ] >>340 あざっす^^
355 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 19:15:01.19 ] >>353 俺は >>350 じゃないので横レスになるが、決める決めないじゃなくて、言語の文化としてより自然なやり方はあると思う。 例えて言うなら、日本語は格助詞があるから語順はある程度自由なはずだが、やっぱり自然な語順はあるだろ。 そんな感じ。 やりたい奴はもちろん最初っから泥臭く書いたってそりゃかまわないが、 たいした理由もないのにあえて泥臭く書くのでは Haskell を使う甲斐が無い。
356 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 20:34:12.21 ] つまりムダなIO発生させていい気になってるってことねw トイならそれでもいいけど実用でそれやったらアホだぞ どれだけキャッシュの無駄遣いすると思ってんだか
357 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 20:55:06.07 ] 別に抽象度高めつつ、無駄なキャッシュも減らすようにできると思うんだが、 どっちもどっちだな〜。 どっちもあほ。
358 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 21:08:23.56 ] >>357 (ふりだしにもどる) 数GBあるログをtailするコードをHaskellで書いてみてくれ
359 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 21:09:07.58 ] とりあえず叩き台としてコード書いてみたよ。 tailFile n h = do seekable <- hIsSeekable h if seekable then do sz <- hFileSize h hSeek h AbsoluteSeek $ max 0 (sz - n) hGetContents h else do takeLast n <$> hGetContents h takeLast n xs = diff xs (genericDrop n xs) where diff xs [] = xs diff (_:xs) (_:ys) = diff xs ys
360 名前: [―{}@{}@{}-] デフォルトの名無しさん mailto:sage [2012/01/24(火) 22:17:01.53 ] d.hatena.ne.jp/slayer845/20120123/1327328227 性能は出ているらしい conduit読めないから俺にはいまいち何やってるか分からんが
361 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 23:33:17.89 ] 批判組早く
362 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 23:42:03.26 ] 手続き型の言語による実装と抽象度では大差ないか劣るのではないか
363 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 23:43:15.57 ] >>359 行数指定できないから0点
364 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 23:55:11.19 ] 晒した勇気に100点をあげたい。
365 名前:デフォルトの名無しさん mailto:sage [2012/01/24(火) 23:58:01.89 ] 間とって50点
366 名前:デフォルトの名無しさん mailto:sage [2012/01/25(水) 00:21:24.87 ] 相乗平均なら0
367 名前:デフォルトの名無しさん mailto:sage [2012/01/25(水) 01:31:32.52 ] 行数指定時用のコードを書いみたよ。 なんとなく遅延IO使ってみたよ。Iteratee使えるならそっちの方がいいんじゃないかな。 hGetLinesReversed :: Handle -> IO [String] hGetLinesReversed h = hFileSize h >>= lazyLoop h [] where lazyLoop h rest pos = unsafeInterleaveIO $ loop h rest pos loop h rest pos | pos < 0 = return [rest] | otherwise = do hSeek h AbsoluteSeek (max (pos-blockSize) 0) xs <- replicateM (fromInteger (min blockSize pos)) (hGetChar h) let (hd:tl) = lines (xs++rest) (reverse tl ++) <$> lazyLoop h hd (pos - blockSize) blockSize = 128