[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 04/25 05:23 / Filesize : 232 KB / Number-of Response : 786
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



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






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<232KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef