関数型プログラミング言語Haskell Part17at TECH
関数型プログラミング言語Haskell Part17 - 暇つぶし2ch373:デフォルトの名無しさん
12/01/25 21:53:21.47
unsafe使わずに書いてみた。
ファイルサイズチェックしてないので、10行無かったり、小さすぎるのは駄目だけどね。

main = do
h <- openFile "test.log" ReadMode
hGetLinesTail h 10 0 >>= putStrLn
hClose h

blockSize = 128
hGetLinesTail h l pos = do
xs <- hGetContentsSeekFromEnd h pos
if l > (length$lines xs) then hGetLinesTail h l (pos + blockSize)
else return xs

hGetContentsSeekFromEnd h pos = do
hSeek h SeekFromEnd (-pos)
replicateM (fromInteger pos) (hGetChar h)


374:デフォルトの名無しさん
12/01/25 21:58:39.36
すまん。インデントがずれてしまった、、、


main = do
  h <- openFile "test.log" ReadMode
  hGetLinesTail h 10 0 >>= putStrLn
  hClose h

blockSize = 128
hGetLinesTail h l pos = do
  xs <- hGetContentsSeekFromEnd h pos
  if l > (length$lines xs) then hGetLinesTail h l (pos + blockSize)
  else return xs

hGetContentsSeekFromEnd h pos = do
  hSeek h SeekFromEnd (-pos)
  replicateM (fromInteger pos) (hGetChar h)

375:デフォルトの名無しさん
12/01/26 15:33:16.32
その言語の背景にあるパラダイムを上手に活用できればスマートな
プログラムになるだろうけど、
強引に別のパラダイムのものに合わせようとすると悲惨になるのは当然じゃろ?
そのパラダイムに応じた方法を模索していくしかないような。
Haskellって他よりパラダイムが明確なだけに得手不得手があるのは
仕方がなさそうよね。

376:デフォルトの名無しさん
12/01/26 16:55:41.77
Unixコマンドは標準入出力をストリームとして扱う点で
関数型言語のパラダイムと親和性があると思うけどな
Broken Pipe

377:デフォルトの名無しさん
12/01/26 17:41:23.30
>>375
結局、メタパラダイムとかいうのは的外れってことだね

378: [―{}@{}@{}-] デフォルトの名無しさん
12/01/26 19:26:22.04
Haskellは関数型+手続き型なのでそんなに極端な得手不得手はない

379:デフォルトの名無しさん
12/01/26 20:04:34.51
そんなに極端な得手不得手はないが、悲惨なことになるのか...

380:デフォルトの名無しさん
12/01/26 20:23:58.12
>>376
標準入出力をストリームとして扱うのはインターフェースの部分
内部では tail が代表するように単純にストリームでは扱っていない

関数型は無限リストや継続などでストリームを上手く表現できるが、
今回話題になっている話はインターフェースじゃなくて内部処理の方

正方向で流れてくる情報を逆方向からたどるというのは、
ある意味ストリームとは対極にある処理だと思う

内部処理もストリームにする事に拘るなら、
逆方向にする時にバッファにため込む必要がある
(たまたま Haskell では遅延評価のおかげでそのバッファ処理を自動化できるが)

381:デフォルトの名無しさん
12/01/26 20:33:13.40
正格評価でもバッファぐらい普通にできるが?

382:デフォルトの名無しさん
12/01/26 20:43:46.18
>>381
正格評価ではバッファを普通にはできない、
と言っているように感じたのか

それなら申し訳ない

遅延評価という仕組みを実現するためのGHCの実装のおかげで、
バッファを作らなきゃいけないことを意識する必要がない
という意味で言ったのだ

念のために言い添えておくと、処理速度などの話とは全く別のことだ

383:デフォルトの名無しさん
12/01/26 21:37:21.78
遅延評価とバッファの関係がよくわからないな。
少なくとも>374のコードは再帰するたびに毎回ファイル末尾から読み直してるようにみえる。
行のサイズ = blockSizeのファイルに対して、
tail nを計算するのにO(n^2)の処理を行っているのでは?

384:デフォルトの名無しさん
12/01/26 22:05:50.63
>>383
> 遅延評価とバッファの関係がよくわからないな。

>>374 のコードは今回の私の話とは全く関係ない
>>376 のストリームの話だ

逆順に指定行数を出力するという処理を「ストリームとして処理」するなら、
順に流入してきたデータを全て一時的にどこかに溜めて(バッファ)、
溜め終わってから、そこのデータの末尾から順に流出させる必要がある

そのバッファをどうやって作るか、どうやってデータの出し入れをするか、
ということが問題になるが、遅延評価を実現する仕組みのおかげで、
Haskell(の大抵の実装)ではそれを意識しなくてもできてしまう
上の方のレスで問題視された「ふつける」に載ってる方法だ

getContents 関数から流出した(リストで表現された)ストリームが
reverse 関数に流入してくる

遅延評価の仕組みにより、reverse 関数はリストの内容は評価しない
後で評価する可能性がある未評価のデータはメモリ内に残り続ける
この部分がストリームを逆順にたどるための「バッファ」の役割を果たしている

385:デフォルトの名無しさん
12/01/26 22:51:34.19
>>383
おっしゃるとおり。
とりあえず、unsafe使わずに書けるかやってみただけで効率は良くない。
ついでに、ちょっと間違ってて10行以上取ってきます。
遅延IO使えばもっとシンプルに効率よく取ってこれるよ。

ちなみに、遅延評価とバッファは全く関係ない。
ファイルを逆から読むのにバッファは必要ない。

386:デフォルトの名無しさん
12/01/26 23:11:31.79
>>385
> ちなみに、遅延評価とバッファは全く関係ない。
> ファイルを逆から読むのにバッファは必要ない。

ファイルを逆から読むのにバッファを必要としない方法もあることは分かっている

>>384 で私が言ったのは、「ストリームとして扱う場合はバッファを必要とする」
ということだ

ストリームというのは、パケット通信などのように、
ある塊のデータ群が一列に順に一つずつ流れる、あるいは流すこと

順に流入してきたものを逆順に流出させるには、バッファが絶対に必要だ
そのバッファの仕組みをプログラマが意識して自分で作る必要があるかどうかは別だが

確かに遅延評価とバッファに直接の関係はない
だが、上記の「ストリームの逆順流出」において
遅延評価を実現させる為の内部の仕組みがたまたまバッファの役割を果たす

もう一度言うが、あくまで >>376 のレスを受けて、
「内部処理もストリームとして扱う場合」の話をしている
(それが非効率的な事も分かっている)

387:デフォルトの名無しさん
12/01/26 23:42:32.23
よくわからん。
もしhGetContentsが遅延評価でなく先行評価だったとしたら、
その「ストリームの逆順流出」プログラムはどう変わるんだ?
どっちにしてもプログラムはhead n $ reverse $ ...
なんじゃないのか。


388:デフォルトの名無しさん
12/01/27 00:05:03.45
>>387
> もしhGetContentsが遅延評価でなく先行評価だったとしたら、
> その「ストリームの逆順流出」プログラムはどう変わるんだ?

そんなことは知らん
先行評価だった場合にGHCが内部でどのような実装をしてくるのか俺には分からない

初めの >>380 では端折ったが、>>382 からはずっと、
遅延評価を実現する為に使われている内部の仕組みが、
ストリームとして流れてくるデータ順の逆転という処理において
バッファとして機能することだけを話しているんだが

ちなみに、この目的で内部の仕組みがバッファとして機能するのは、
hGetContents の処理ではなく reverse の処理をGHCが実行ファイルに埋め込む部分だ


389:デフォルトの名無しさん
12/01/27 00:07:50.19
おれは言わんとしてることがわかったけど、
もう少しわかりやすく説明したほうがいいと思うよ。

390:デフォルトの名無しさん
12/01/27 00:20:31.26
>>389
了解した、努力する

391:デフォルトの名無しさん
12/01/27 00:21:30.05
説明ぷりーず。
一応、WHNF簡約やGHCのSTGマシンあたりの実装は理解してるつもり。

392:デフォルトの名無しさん
12/01/27 00:43:19.91
チュートリアルをやってるのですが、最初で詰まってます。
以下のboomBangsという関数定義でチュートリアルのままなのですが、自分の環境だとエラーになります。
どこが間違ってるのでしょうか。ghci 6.12.1です。
Prelude> boomBangs xs = [if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

<interactive>:1:13: parse error on input `='
Prelude>

どうかよろしくお願いします。


393:デフォルトの名無しさん
12/01/27 00:55:24.00
Prelude> let boomBangs xs = [if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

394:デフォルトの名無しさん
12/01/27 01:05:23.28
動きました。ありがとうございました。
Prelude> let boomBangs xs = [if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
*** Parser:
*** Desugar:
*** Simplify:
*** CorePrep:
*** ByteCodeGen:
Prelude> boomBangs [1,2,3,4,5]
*** Parser:
*** Desugar:
*** Simplify:
*** CorePrep:
*** ByteCodeGen:
["BOOM!","BOOM!","BOOM!"]


395:デフォルトの名無しさん
12/01/27 01:13:49.09
>>391
あんまり難しい話じゃなくて、C言語とかでも、Seekなしで、
ファイルの先頭からシーケンシャルアクセスしかできないとしたら、
最後10行のデータ取ろうと思うと、どうしても直近10行はバッファ
しとかないといけないでしょ?

Haskellは、このバッファを意識しないでも、自動でやってくれる
って言ってるんだと思うよ。

遅延評価がバッファしてるわけじゃないけど、バッファしてるように
見えなくもない。

396:デフォルトの名無しさん
12/01/27 02:26:27.98
Haskellも結局クリーンで美しいカルト言語だったんだお
設計外のことを無理にやらせれて破綻するんだお

397:デフォルトの名無しさん
12/01/27 02:49:49.78
ということにしたいのれすね?

398:デフォルトの名無しさん
12/01/27 03:01:28.89
実際にやってみたけど、「ふつうの」に書いてある元々の「効率の悪い」
tail に 10 GB ていどのファイルを食わせても、5 秒もかからないんだよね。
これが分単位になるのなら考えてもいいけど、そうでなければ簡潔さの
ほうが大事だと思う。

“「効率」についてうんぬんする人々は、たいていの場合主として本番計算に
計算機資源がどのくらい使われるか、という点にばかり着目していて、コンパ
イルしたり、虫取りしたり、その他さまざまなやりそこないをしたりしながら
本番計算にそなえるために消費される人間の時間と計算機の時間を考えに入れ
ていないのである。” (ソフトウェア作法 p.132)





399:デフォルトの名無しさん
12/01/27 03:03:28.54
ごめん、10GB は嘘だわ。10MB ね。


400:デフォルトの名無しさん
12/01/27 03:13:57.42
ちなみに自分は後ろから読む tail コマンドを昔 C (Pascal だったかも)で書
いてみたことがあるけど、
* ファイルが改行で終わる場合と終わっていない場合を分ける
* バッファの先頭から行がはじまっているか、その前からつながっているかを分ける
とか、細かい場合分けがあって、予想したより面倒だった。



401:デフォルトの名無しさん
12/01/27 05:53:27.42
>>395
正格評価でも、明示的にバッファ取らなくても、
パラメータ渡しをバッファ代わりにできますし…


402:デフォルトの名無しさん
12/01/27 05:56:04.14
>>398
> これが分単位になるのなら考えてもいいけど、そうでなければ簡潔さの
> ほうが大事だと思う。

んなこたーない。

> “「効率」についてうんぬんする人々は、たいていの場合主として本番計算に
> 計算機資源がどのくらい使われるか、という点にばかり着目していて、コンパ
> イルしたり、虫取りしたり、その他さまざまなやりそこないをしたりしながら
> 本番計算にそなえるために消費される人間の時間と計算機の時間を考えに入れ
> ていないのである。” (ソフトウェア作法 p.132)

これは数回実行するだけの研究用プログラムについては正しいが、
UNIXのtailコマンドのように1度書かれたソースを莫大な回数実行する場合には
詰められる無駄は詰めたほうがいい。

403:デフォルトの名無しさん
12/01/27 06:59:03.58
正格な評価でも10行分のキューにストリームから一行読んでは突っ込んでいくだけでしょ
別にC言語でも数分で書けるから特にHaskellを使う利点はないよね

404:デフォルトの名無しさん
12/01/27 07:36:42.85
>>401
同じ事を繰り返すが
私は正格評価の事については一言も触れいてない
正格評価ではバッファを意識する必要がある、
なんて私のレスが何処かに書いてあるか?

私は一貫して
・ストリームとして処理するならバッファが必要
・遅延評価を実現する仕組みがバッファとして機能している
この2点しか述べていない

「遅延評価とバッファの関係」を質問されたから、
正格評価の事まで話に絡める必要は無いだろ
別に遅延評価vs正格評価でどちらが有利か戦わせているわけではない

正格評価でも明示的にバッファ取らなくてもいい
と貴方が言うのなら、きっとそうなんだろ
それは私の話とはたぶん関係ないと思うから、
それがどうかしたのか、としか言いようがない

ちなみに、私の話とは別の事として訊くのだが、
> パラメータ渡しをバッファ代わりにする
それはパラメータでバッファを渡しているのではないか?
遅延評価を実現する仕組みでたまたま機能するバッファの方は、
バッファを作っているという意識すら感じずにプログラムできるが

「正格評価+ストリーミング処理+パラメータ渡し」
これでバッファを意識しなくてもいいプログラムを書いてみてくれ
ちょっと興味ある

405:デフォルトの名無しさん
12/01/27 07:46:54.83
引数として先頭トークンと継続を渡せばいいんじゃね?

406:デフォルトの名無しさん
12/01/27 07:49:56.57
>>391

以下の部分で遅延評価とバッファの関係を簡単に述べている
どこの部分の詳細な説明を求めているのか具体的に言ってほしい

>>384
> 遅延評価の仕組みにより、reverse 関数はリストの内容は評価しない
> 後で評価する可能性がある未評価のデータはメモリ内に残り続ける
> この部分がストリームを逆順にたどるための「バッファ」の役割を果たしている

407:デフォルトの名無しさん
12/01/27 08:04:10.58
アホかHaskellでもバッファは意識しろよ
そんなんだからアホ的非効率コードを書くんだよ

408:デフォルトの名無しさん
12/01/27 08:13:37.12
どうでも良くなってきたが、、、

正格評価、遅延評価とかはバッファと関係ないと思います。
というか、バッファされてる時点で評価済みで遅延してない、、、

正格でも遅延でもたぶん同じように書けます。

409:デフォルトの名無しさん
12/01/27 08:23:27.08
手元にある一番大きなプレーンテキストは MySQL のダンプ(1.3GB)だったので,
これを「ふつうのHaskell」版の tail コマンドに食わせてみたが、メモリオー
バーで時間計測できず(笑)。ファイル丸ごと reverse はさすがにないな。

ただ、個人的にはテキストファイルをランダムアクセスするのは(使用言語が何
であれ)プログラムが無意味に複雑化するので反対。sort とかなら高速化の意
味はあるだろうけれど、tail コマンドをそんなに速くしてどうするの、っていう
かんじ。

Haskell なら、このていどでいいはず。これなら本にのせても場所を取らないし、
大きなファイルでも動作する。

import System
dotail :: Int -> [a] -> [a]
dotail n xs = if null (drop n xs) then take n xs else dotail n $ tail xs
main = do {args <- getArgs; cs <- getContents;
  putStr $ unlines $ dotail (read (head args)::Int) (lines cs)}

1.3 GB で 13分だった。Haskell の入出力の遅さを考えればまあまあじゃないかな。

ちなみに同じファイルに対して行数カウント getContents >>= print.length.lines
だと 8分35秒。Java (BufferedReader.readLine 使用) や Perl で同じことを
やると1分40秒から 1分50秒くらい。wc -l コマンドだと 36秒。


410:デフォルトの名無しさん
12/01/27 08:30:16.99
おまいらこのあとは tail -f の実装が待ってますよ

411:デフォルトの名無しさん
12/01/27 10:25:32.57
ふつうに実装するとIO (IO String)が出てくるから
それよりはunsafeでもIO [String]にしたいってことなのか

412:デフォルトの名無しさん
12/01/27 10:39:57.79
System.IO.MMap.Lazy

413:デフォルトの名無しさん
12/01/27 11:12:49.26
tailなんて巨大ログをすばやく確認したい時ぐらいなんだから
いちいち先頭から1行ずつ読むとか糞遅かったら誰も使わんだろ
用途を満たさない物なんか設計してどうする
言語の作法なんて関係ない

414:デフォルトの名無しさん
12/01/27 11:16:44.14
>>410
それは簡単じゃない?
Control.Concurrent の threadWaitRead で待って、サイズが変わってたら
その分を出力するだけでしょ。



415:デフォルトの名無しさん
12/01/27 11:32:02.97
俺がtail使うのはファイルよりpipeのほうが多いな

416:デフォルトの名無しさん
12/01/27 12:06:04.37
ここで問われているのは、
長年GNUがやってきたように、
過去の他人の成果を丸パクリして、
それでも使われるレベルになるのかどうか?
ということだよな

417:デフォルトの名無しさん
12/01/27 12:47:47.33
儲かるレベルにはならないからポジショントークをする人がひとりもいない
という成果に期待しよう

418:デフォルトの名無しさん
12/01/27 14:20:57.31
クソ実装でも十分速いとか言ってる香具師がいるけど、
空読みするファイルが分散fs上に乗ってたら悲惨だなw

419:デフォルトの名無しさん
12/01/27 16:51:25.37
標準だけで教科書的に綺麗に書くようなオナニーは卒業して
仕事でHaskell使っている人が苦心の末発明したcondoitの使い方覚えろよ

420:デフォルトの名無しさん
12/01/27 17:07:01.50
なにそのコンドームみたいなの?

421:デフォルトの名無しさん
12/01/27 17:09:06.72
conduit

422:デフォルトの名無しさん
12/01/27 18:37:45.13
あれだこれだと意見はいろいろあるだろうが、
にコードが出てきたのがなんと言っても尊い。

423:デフォルトの名無しさん
12/01/28 11:33:31.74
>>288
Template Haskell を少し勉強してみたところ、
やりたいことが実現できそうなことが分かりました

例えば次のように引数をコンパイル時に制限できるんですね

f :: Int -> ExpQ
f x | x < 0 = fail "error"
  | otherwise = [| x |]

$(f (-1)) ====> error
$(f 3) ====> 3

このような事を値構築子でできるようにすれば良いわけですね
調べてみます

ありがとうございました

424:デフォルトの名無しさん
12/01/29 09:15:33.67
URLリンク(jutememo.blogspot.com)

リストの要素を入れ替えるswap関数は、pythonの方が簡潔なんだな・・・
リストを配列みたいに扱えない言語よりは優位なんだろうけど、そう言う言語と比較するときは配列と比較になるしなぁ・・・


425:デフォルトの名無しさん
12/01/29 09:30:41.60
リストのランダムアクセスは遅いから専用の関数が用意されてないだけ
Data.Sequenceならupdateがあるので簡単
swap :: Int -> Int -> Seq a -> Seq a
swap i j s = update i (s `index` j) $ update j (s `index` i) s

426:デフォルトの名無しさん
12/01/29 09:37:27.18
よく言語Aより言語Bの方が処理(計算)xを簡単に書ける、というけどさ

言いたいことは分かるけど、「具体的な処理」に関して、
処理後に同じ結果が得られる複数の言語間で「簡潔さを比較」する意味って何なの?

>>424 のリストの swap だって、一旦関数にしてしまえば、
あとは Haskell でも同じように簡潔に書けると思うんだが
(それがライブラリの大きな役割の一つだし)

>>424 のリンク先で考察している方法それ自体は面白いし興味あるけどね

427:デフォルトの名無しさん
12/01/29 09:44:58.64
>>426
いろいろな具体的な(既知の)処理を簡潔に書ける言語があれば、
アプリケーション固有の(未知の)処理も簡潔に書ける可能性が高いからだろ
未知の処理だって、なんらかの既知の処理に似ていることが殆どだ
ということを加味すればなおさら

428:デフォルトの名無しさん
12/01/29 09:53:41.16
そりゃ、できることを比較したらどれも同じになるから比較にならんだろ。

言語の比較は、簡潔に書きやすいとかできるコードが速いとか、デバッグ
しやすいとかになるわ。ライブラリだって簡潔に書けるほうが充実させや
すいしな。

429:デフォルトの名無しさん
12/01/29 10:07:36.20
ハスケルのほうが簡単に書ける時には
「ハスケル最強」

ハスケルのほうが煩雑になってしまう時には
「そんな比較意味なくね?」

430:デフォルトの名無しさん
12/01/29 10:15:41.39
>>429
それは、逆も同じだけどね。

ハスケルのほうが簡単に書ける時には
「そんなの意味なくね」
ハスケルのほうが煩雑になってしまう時には
「ハスケル使えねぇ」

用途考えずに比較なんて意味ないね。

431:デフォルトの名無しさん
12/01/29 10:35:32.33
>>427
いや、だから一度関数になってしまえば、「簡潔さはほぼ同じ」になるわけでしょ

最初に比較して言語Aの方が簡潔だった、でも関数にしたから言語Bも同じなった
>>424 の言う「優位な言語」というのは、どの時点で比較したものなの?
仮に言語Bが関数化した結果、言語Aよりも簡潔になったら、言語間の優位さは逆転するの?

そういうことで逆転してしまうのなら、それはその「具体的な処理に関する」
簡潔さの言語間の比較とは言えないだろう
その具体的な処理に被せるインターフェースの部分のおかげで簡潔になったのだから

また、そんなことで逆転したとは言えないのなら、そもそも比較して
言語Aの方が優位だとか言うことの意義が見いだせない
私の経験上、実用的なアプリ内の数多ある個別具体的な処理に関して、
それらを最も得意とする言語(やパラダイム)は複数に分散する
ある特定の処理をするのに言語Aが優位だからという理由で、
そのアプリを作るのに言語Aを選ぶことは、実際のところ滅多にない
普通は自分やチームが得意としている言語であったり、
個別具体的な処理ではなく全体の求められる処理速度やメンテのしやすさなどで決定される

>>428
今の時代、広く使われている言語なら、どの言語でもライブラリは充実している
充実度の差の理由に言語の簡潔さが関わる割合は、比較して議論するほど高くはないと思うが

432:デフォルトの名無しさん
12/01/29 10:58:44.59
ある処理を実験する複数のプログラムを一つのファイルに書いていました。
(初めはファイルを分けるのが面倒に思えたから)

あるプログラムを実験するときは別のプログラムをコメントアウトしたりして。
なので、ファイルのトップには import が大量に書かれています。

実験が終わって、採用するプログラムを一つに絞ったので、
それを正式にちゃんとしたファイルに分けて保存したいのですが、
そのプログラムを実行するのにどの import が必要なのか、
ごちゃごちゃしてて分からなくなりました。

とりあえずそのプログラムだけ別ファイルに移してコンパイルしてみて、
モジュール不足の為にコンパイルエラーが出る度に
import を追加していけばいいとは思いますが・・・(以前も同じ様なことをしてた)

もっと簡単に、あるソースファイル内の識別子を評価するのに不足していて、
かつインストール済みであるライブラリのモジュールの一覧を見る方法はありませんか。

433:427
12/01/29 11:08:59.81
>>431
俺は>>424じゃないけど、関数化の前の話をしているつもりだった

>また、そんなことで逆転したとは言えないのなら、そもそも比較して
>言語Aの方が優位だとか言うことの意義が見いだせない
>私の経験上、実用的なアプリ内の数多ある個別具体的な処理に関して、
>それらを最も得意とする言語(やパラダイム)は複数に分散する
もちろん。でも、実際的なアプリが色んな処理から成っているからこそ、
言語には極端な苦手分野がないほうが良いし、なるべく広範囲のコードを
簡潔に書けるのが良いということになる
たとえばランダムアクセス可能なデータ構造をすごく扱いにくい言語があったら、
その言語で書き易いアプリはかなり限定される

それから、アプリごとに多用される処理の傾向も違う
行列演算中心のアプリもあるし、DBアクセス中心のアプリもあるし、両方やるのもある

434:デフォルトの名無しさん
12/01/29 11:13:25.04
>>432
全部のファイルに全部のimportをコピーして、とりあえずコンパイルを通す
コンパイルが通ったら-fwarn-unused-importsで不要なインポートを一掃

435:デフォルトの名無しさん
12/01/29 11:16:53.53
>>431
長くて読む気しないな。
言語比較なんてナンセンスだと思うが。言語の優劣なんて個人個人で違うし。

関数化すれば0になるかもしれないけど、関数化するまでのコストは?
ライブラリになってないところの、作成コストは?
ライブラリの学習コストは?

ライブラリは十分充実してる?そしたら自分でプログラムなんて書かんわ。

436:デフォルトの名無しさん
12/01/29 11:30:01.60
>>434
なるほど、逆でしたか
不要な import を省いていくんですね

ありがとうございました

437:デフォルトの名無しさん
12/01/29 12:41:36.12
>>431
うーん、同じ処理の関数化の比較は、コードの長さとかだけじゃなく、関数化する際の概念とか手法とかがプログラマ・あるいは初心者に思いつきやすいか?とかの意味でも比較の意味はあると思う。
>>424のURL先ではpythonは配列的にも使えるリストのために、値の交換が得意な配列的な処理になってるけど、配列は配列。リストはリストとして扱う手続き型言語の場合、

1、リストの中身を配列に移す
2、配列で値を交換
3、配列の中身をリストに戻す

と言う処理になる

Haskellだと

>>424の9つの方法の内、初心者にも出来そうな一つ目と二つ目の方法は基本
1.リストを分割する
(iより前のリスト、i、iとjの間のリスト、j、jの後ろのリスト)
2.値を交換した状態のリストとして結合しなおす

という処理になる




438:デフォルトの名無しさん
12/01/29 12:53:23.82
>>437
> 1、リストの中身を配列に移す
> 2、配列で値を交換
> 3、配列の中身をリストに戻す
>
> と言う処理になる

そんな馬鹿なコードを書くのはプログラム初めて1ヶ月とかの初心者だけだろw

439:デフォルトの名無しさん
12/01/29 12:55:50.74
>>438
え、確かにリストのままでも配列的に使えるけど、パフォーマンス的にはこちらは今でも有効だと思うけど・・・


440:デフォルトの名無しさん
12/01/29 13:03:38.33
たった1組のswapにそんなことしてたら大爆笑だよw

441:デフォルトの名無しさん
12/01/29 13:05:40.34
>>437
で、swapの実装という単位で比較した結果、言語Aの方が
関数化する際の概念とか手法とかがプログラマ・あるいは初心者に思いつきやすい
と結論づけられたとして、それからどうなるの?
それが何にどのように、どれくらい活かされる?

例えばHaskellという一言語においてリストをswapするいくつかの方法の中で、
簡潔さ、初心者の理解のしやすさ、計算速度、応用の幅・・・
などで互いに比較しすることの意義は分かる
時と場合によって使い分ける際の自分なりの基準になる

しかし、今存在している言語間で、swap処理などの
抽象度の低い低レベルレイヤーの処理の実装を比較して
優劣を考える意義がよく分からない

せいぜい新言語を作る際に、既存言語を分析する時ぐらいしか、
言語間で比較して優劣を考える意義はなくないか?

442:デフォルトの名無しさん
12/01/29 13:05:46.19
>>440
じゃあ、どういう処理を1ヶ月以上たったらしてるの?


443:デフォルトの名無しさん
12/01/29 13:15:46.01
たまにはArrayのことも思い出してやってください

444:デフォルトの名無しさん
12/01/29 13:17:38.11
>>442
リスト処理を解説する初心者レベルの入門書で
スワップ時にリストの中身を配列に移すなんて方法は、普通は教えない

普通は、双方向リスト・単方向リストの要素がリンクで結ばれていることをまず教える
もしスワップ処理を教えるなら当然その後になるが、
その際はリンクを繋ぎ替える処理で実装する方法を教えるだろう

処理速度云々ではなく、その方が初心者が「リスト処理を理解しやすい」からだ
初心者はリストの特徴を学ぶのが大事だからな

だから、一ヶ月と言わず、初めから配列に移すなんて方法は学ばない

445:デフォルトの名無しさん
12/01/29 13:23:20.30
n回のswap処理をするのであれば、1度配列にコピってからn回swapするだろうが、
たった1回のswapのために配列にコピってswapしてリストを再構築するとか、アホだろ。


446:デフォルトの名無しさん
12/01/29 13:23:33.53
>>441
今はサイト自体(と運営会社)が無くなっちゃったけど、Haskell入門以前という、プログラミング全くの初心者向けのブログ書いてたんだ
(そして、ネット上の友達(プログラミング未経験者)に読んでもらって、理解できるか確認しながら書いてた)

その関係で、PCがどうやって動いてるかも理解できてない人向けの言語を探してたり
そういう意味で、Haskellは割りと有効だとは思ってたんだけど、このswap関数でちょっと心が揺らいでたり
(変数の概念とかも数学から離れていないと言う意味で、数学+α程度の知識でプログラミングできる言語だと思う)


447:デフォルトの名無しさん
12/01/29 13:24:16.02
>>443
Array=配列 ですが、何か


448:デフォルトの名無しさん
12/01/29 13:24:26.38
まーたこれで数日後にRubyスレが荒れるのか

449:デフォルトの名無しさん
12/01/29 13:26:31.49
>>444
ん・・・
それって、結局Haskellのやり方と同じことを手続き型言語でもリストのswapの勉強の際には教えるってこと?


450:デフォルトの名無しさん
12/01/29 13:28:51.88
>>445
何というか・・・
行間嫁よ
そんなの当たり前だろ


451:デフォルトの名無しさん
12/01/29 13:31:51.09
>>448
rubyの場合、リストっぽく使える配列だね
pythonとは名前が逆だけど、実装は何が違うんだろう?


452:デフォルトの名無しさん
12/01/29 13:36:38.70
>>450
はあ?文脈読んでないのはオマエだろ。
>>424のリンク先のコードのswap関数の型を書いてみろよ。
どこをどう見たって、リスト/配列中の1組の値のswapだ。
型情報以上に重要な「行間」があるなら書いてみろw

453:デフォルトの名無しさん
12/01/29 13:45:07.16
>>449
結果としてHaskellのやり方と同じことを初心者には教えることになるが、
そんなことが言いたかったのではないんだ

・一般的にリストと呼ばれている構造をプログラムで表現する方法
・その表現方法の上での、リストに関する様々な演算方法

リスト処理を初心者に教える入門書はこの2点を分かってもらいたくて書いている

Haskell でのプリミティブなリストの表現方法はいわゆる前方参照の単方向リストだが、
概念は他言語で表現されたリストと似ているし、表現方法が同じなら同じ方法が使える

もし swap 処理を教えるとしたら、その概念に沿って教えるのが自然だ
概念から外れた方法を理解させようとしている入門書があるなら、
その入門書は(少なくともその部分に関しては)クソだと思う

454:デフォルトの名無しさん
12/01/29 14:12:10.92
>>452
視野が狭いな・・・


455:デフォルトの名無しさん
12/01/29 14:25:57.63
>>453
リスト専門の入門書ってのは読んだこと無いんだが、もし在るならそうなるだろうね
Haskellでちょっと不便かな?と思ったのは配列も値が変えられないだろうという事。結局、IOモナドなり、Stateモナドなりを頼る事になりそうなのがね・・・
>>425のupdate関数は初心者にも作れるし、意外と有効かも
(全体を2回書き換える事にはなるが、コード上は交換したい値を一つずつ更新してるのは、初心者には分かりやすそう)

最近はリストなんだか配列なんだかという、(コード上の)データ構造の性質がハッキリしない言語が多くなってきたから、楽にはなったけど、データ構造の性質を教えるのにはちょっと不便になってきた気がする
(そう言う意味では、Cとかの方が生々しい意味で最適なのかも知れないが、生々しすぎて初心者には敷居が高いし・・・)


456:453
12/01/29 14:33:26.96
>>449
読み返したら誤解を与えそうな感じがするから言っておくが

一般的なリストの構造とリストの演算を初心者に教える過程で swap を教えるのなら、
結果としてHaskellのやり方と同じことを教えることになる、という事だからな

要素の破壊的な代入が許されるタイプのリストなら、
普通の変数同士のswapのようにテンポラリ変数を使って比較的素早くswapできるし、
そのように解説している入門書もあるだろうが、それは目的が違う
その部分の関しては、リストの構造とリストの演算を学ばせるためじゃない
(喩えは悪いかもだが、方程式の解法で移項というテクニックを教えるようなもの)

457:453
12/01/29 14:34:53.97
レス前にリロードしとけば良かった orz

458:デフォルトの名無しさん
12/01/29 14:41:52.19
>>456
いや、ありがとう
他人に書かれてもドンマイだよ

変数の値が書き換わるのが理解出来ない初心者(かなり稀なパターン)へ手を替え品を替え説明するのに比べれば。。。

変数が箱って言う例えは誰が考えたんだよ。。。


459:453
12/01/29 14:48:17.90
数学で式に文字が導入された頃から漠然とした箱のイメージはあったと思う

値と変数を束縛して固定するイメージよりは、
値を入れるための箱のイメージの方が先にあったのではないか

と、大して根拠もなく個人的には思ってる

460:デフォルトの名無しさん
12/01/29 15:00:35.95
>>459
それは分かる。つーか、自分も似た感覚なんだが、箱の中身がコピーされるとか、新しい値を入れると消えちゃうとかの説明がね。。。
箱じゃ無くて1個のみのスタックみたいなところてん式(追い出された値は捨てられる)の説明でもコピーが説明出来ないしね。。。

まあ、そいつがバカ過ぎなのが問題なんだけど、普通の人はメモリって何?が基準だしなぁ。。。と、基本的な事柄は紙の上で説明出来るのがベストなのかなぁ。。。とか考えてhaskellに流れ着いてたり

ちょっとコンピュータの仕組み齧れば普通の言語の方が自然なんだが。。。



461:453
12/01/29 15:15:26.29
>>460
私がC言語を初心者に教えている時は、一般的な「変数=箱」のような喩えではなく、
もう初めから「変数=メモリアドレスの別名」と直に教える
そして、メモリとはどういう構造か、その上でどんな事ができるかを教えてる

当然メモリって何?が基準だけど、C言語ならそこから逃げられないし
喩えると余計に分かりにくい

Haskellを初心者に教えた事は一度しかないけど、
その時も箱とかの喩え話じゃなく、「変数=値の別名」と直に束縛の概念を教えた

462:デフォルトの名無しさん
12/01/29 15:36:15.61
>>461
自分も結局、変数=値の別名で教えた
おバカなその人はhaskellも無い頃の思い出だが、cpuの仕組み習ってる筈なのに(情報技術科の同級生)、全く理解出来てなかった
そこまでのバカは捨て置いても良いと思うんだけど、手続き型だとスコープの問題もあるのよね。。。
関数内でswapしたのに値が変わってない!!とか
ガッコの先生じゃ無いから、放っときゃ良いんだけど、なるべくそう言う「?」が無い言語が望ましいんじゃ無いかと

本気でプログラマ目指すなら、多分javaやC#しか使わなくても、Cでメモリの概念を直接覚える必要があるだろうな。とは思う
(C#は限定的でもポインタ残してたのは、本当に英断だった)


463:デフォルトの名無しさん
12/01/29 18:06:25.05
>>454
おまえは心が狭いな
素直に自分の間違いを認めればいいのに

464:デフォルトの名無しさん
12/01/29 19:00:27.45
>>463
1、リストの中身を配列に移す
2、配列で値を交換
3、配列の中身をリストに戻す

って書いてて、値の交換が何度も必要な場面で毎回リストに戻す馬鹿がどこに居るよ
行間嫁ってのは、そう言うこと
そんな応用力無い奴はプログラマになれないだろが


465:デフォルトの名無しさん
12/01/29 21:03:37.16
C言語から入るとやたらとメモリの無駄遣いが
気になるのはあるね。

swapは、配列の発想から抜け出せないから出てこないだけで、
リストだと思えば、切ってポインタ繋ぎかえるだけじゃんと思いつくと思う。

Haskellだと、こんな感じか。

swap i j l = let
  (cs,d:ds) = splitAt j l
  (as,b:bs) = splitAt i cs
  in as++[d]++bs++[b]++ds

まぁ、swapくらい標準で用意して欲しい気はする。

466:デフォルトの名無しさん
12/01/29 21:20:50.26
リストでインデックス指定のswapが必要になる時点で型の選択を間違ってる気がしないでもない
綺麗事だけどさ

467:デフォルトの名無しさん
12/01/29 21:50:07.46
まぁ、他のリスト計算(++ や fold系、zip系など)に比べると、
swap の需要は圧倒的に少ないわな

正直、今まで必要になった事があったのかどうか思い出せん

468:デフォルトの名無しさん
12/01/29 22:09:42.45
swapは、Sortに使うね。
Haskellは、Sort簡単だからあまり出番がないのかも。

でも、Sliceは欲しいな。

469:デフォルトの名無しさん
12/01/29 22:38:39.26
>>468
Haskell のリストのソートに swap は使わないだろ
効率的なマージソートの実装が標準ライブラリに既にあるじゃん

ソート関数を自作してまで swap を使う理由は何?

470:デフォルトの名無しさん
12/01/29 22:45:28.87
>>468
マージソートにも、クイックソートにもswap使わないけどね・・・


471:デフォルトの名無しさん
12/01/29 22:52:38.26
いや、別にHaskellの話してたわけじゃないけどな。
swapって言ったらCのqsortなんかが真っ先に思いついたわけだ。

でもって、まぁHaskellじゃ使わんなと思って出番がないと書いたんだが、、、
しょうもないことに一々絡まんでも。

というか、C言語とかあんま使ったことないでしょ?

472:デフォルトの名無しさん
12/01/29 23:11:17.90
>>471
絡むってほどのつもりでもなかったけど・・・
Cは確かにあまり使ってないなぁ・・・

最近は、データ構造の定義がHaskellと似てるなー・・・とか思いながら、ぼんやり復習してるけど


473:デフォルトの名無しさん
12/01/29 23:18:12.48
>>471
俺も別に絡むわけじゃないが

>>468 では Haskell で swap の出番があまりない理由が
「Haskell では sort が簡単だから」に見たから

もし仮に Haskell の標準ライブラリで sort が実装されてなかったら、
swap を使って実装する気だったのかなと思って

474:デフォルトの名無しさん
12/01/29 23:28:13.17
よくよく考えてみると
swapの最大の利点はデータの長さを変えずに済むことなんだよな
だから配列操作に有難がられるわけだ

475:470 de 472
12/01/30 00:04:53.69
>>473
ごめん・・・
標準でsortあるの?
Haskell入門中で、マージソートもクイックソートも自作したけど、swap使わんかったんで書き込んだんだけど、sort関数あるの知らんかった・・・
ソートって、基本、交換じゃなくて、並べ替えだから、リストの切り貼りで出来るから、swap要らんという意味だったのかと・・・
たぶん、純粋に交換したい時しかswap使わないと思われ
要素が少なかったら、コード上で直接交換できるし・・・

--3要素のリスト限定。(大抵、こういう処理はタプルでするっぽいけど)
swap3rd a:b:c:[] = c:b:a:[]




476:デフォルトの名無しさん
12/01/30 00:12:01.81
>>475
> Haskell入門中で、マージソートもクイックソートも自作したけど

それは大変素晴らしいことだ

ただ、ソート関数自体は Data.List に既にある
ライブラリドキュメントを見てみ
(そのドキュメントからソースの中身も見れる)

477:デフォルトの名無しさん
12/01/30 00:29:00.75
>>476
・・・orz
ま、まあ、元々アルゴリズムの勉強不足だったから、良いんですけどね・・・


478:デフォルトの名無しさん
12/01/30 08:40:36.13
マージソートはswapじゃなくてリストを対象としてできるぞ?

479:デフォルトの名無しさん
12/01/30 10:55:57.11
ソートがないと思えるのも、
これまた凄い感覚で好きだぜw

480:デフォルトの名無しさん
12/01/30 18:27:21.44
>>464
おまえ、正真正銘の馬鹿だな。
>>424のリンク先は1組swapする関数で、以後それをベースにした議論が続いていた。
>>424とは異なる前提で議論をしたければ、それを示せ。それが議論ってもんだ。
自分の勝手な妄想が他人にも共有されていると思うほうが
よほど応用力がないオナニー野郎だ。

自分の勝手な妄想を行間などと呼んで、他人にも自動的に賛同してもらえているなど、
正常な判断能力を持つ人間とは考えられない。病院いけ。

481:デフォルトの名無しさん
12/01/30 19:37:07.68
>>480
それをいうなら、>>445で最初に前提覆してるのはおまいさんだろ・・・
と言うか、自分もおまいさんと同じ意見のつもりで>>437書いてたんだが?

swapは

> 1、リストの中身を配列に移す
> 2、配列で値を交換
> 3、配列の中身をリストに戻す

の2で使うだけだろ
1と3は前処理と後処理

それをおまいさんが>>438で煽るから、どんな画期的な手法が出てくるのかと期待してたのに・・・


482:デフォルトの名無しさん
12/01/30 19:47:22.37
>>481
すまんが、>>445はn回まとめてswapを「否定する」内容だと思うぞ。


483:デフォルトの名無しさん
12/01/30 19:51:58.64
>>481
> swapは
>
> > 1、リストの中身を配列に移す
> > 2、配列で値を交換
> > 3、配列の中身をリストに戻す
>
> の2で使うだけだろ
> 1と3は前処理と後処理

え?1,2,3全部で「リスト要素対のswap」じゃないのか?
実際、>>424のリンク先のコードも「リスト要素対のswap」だし。

冷静になって論点を整理してみたら?俺は>>438に同意だ。
「リスト要素対のswap」の実装で配列にコピーしてからswapして
またリストを作りなおすとか、最初にeliminateする実装だ。

484:デフォルトの名無しさん
12/01/30 20:11:13.37
>>482
なるほど、合点がいった
じゃあ、結局、たった一回リストの中身を交換するswap関数は、Cのようにリストと配列がはっきりデータ構造として区別された言語ではどのような処理を行うのがベテランの手法なのだろう・・・
その回答は出てない気がする
私はベテランではないし、最早、>>438に初心者認定されてるしな


485:デフォルトの名無しさん
12/01/30 20:59:22.54
>>480
話と全く関係ないが、感動した。そうだ行間、行間だ。
行間を読めというやつは何処か特徴的だ。

486:デフォルトの名無しさん
12/01/30 22:59:47.18
唐突だが、monad-parallel パッケージってめっちゃ便利だな

例えば複数のIOモナドをひとつのリストに全て入れて
Control.Monad.Parallel.sequence_ 呼べば勝手に並列処理してくれる

プログラムソースが非常にスッキリした
今まで pseq や par を駆使してたのがアホらしくなったわ
(monad-parallel パッケージの中で駆使されているんだが)

487:デフォルトの名無しさん
12/01/31 18:43:29.33
5 :: Int と 5 :: Integerと何が違うのですか?


488:デフォルトの名無しさん
12/01/31 19:16:11.30
>>487
5::Int の型は Int になって、
5::Integer の型は Integer 型になる

よって、この 5 の部分が例えば 2147483648 だと結果の値が変わってくる

489:デフォルトの名無しさん
12/01/31 19:21:46.24
>>487
Intは31ビットで表現できる範囲の整数しか扱えないが、速い(C言語で言うところのintだが、1ビットは型推論に使用)
Integerはメモリの許す限り大きな整数も扱えるが、遅い


490:デフォルトの名無しさん
12/01/31 19:40:11.07
>>489
GHCのIntは32ビットまたは64ビットだよ
Intが31ビットの処理系があってもいいけど、余った1ビットの用途は普通GCで型推論じゃないよ

491:デフォルトの名無しさん
12/01/31 19:42:57.63
objectの型をあらわすタグかな?

492:デフォルトの名無しさん
12/01/31 19:59:59.24
>>490
ごめん。GCだったっけ
Javaとかは31ビットとか無いよなー・・・とか考えて、型推論にしたけど、確かに昔31ビットって聞いたんだが、改めてググってみたら、昔は30ビット、あるいは31ビットだったけど、今は32ビットなんだな。
(64ビットコンパイラは64ビットInt)

URLリンク(www.haskell.org)


493:デフォルトの名無しさん
12/01/31 20:32:31.44
simonpj先生らのboxing/unboxing研究のおかげ。> word一杯のInt

494:デフォルトの名無しさん
12/02/01 12:33:11.89
 URLリンク(www.snoyman.com)

495:デフォルトの名無しさん
12/02/01 12:35:57.99
>>494
HaskellでのWebフレームワークは面白そうだから興味はあるんだが、いかんせん、
遊びでやるにしてもその前に学ばなければならないことが多いんだよな

496:デフォルトの名無しさん
12/02/01 12:41:38.35
僕のweb framework処女はyesodに捧げます><

497:デフォルトの名無しさん
12/02/01 13:38:07.92
>>494
こういうのが本になっちゃう所がすごいね
URLリンク(shop.oreilly.com)

498:デフォルトの名無しさん
12/02/01 15:00:41.95
オライリーの中の人の選球眼が良いんだろうねぇ

499:デフォルトの名無しさん
12/02/01 15:03:27.03
すのいまんは108人いる

500:デフォルトの名無しさん
12/02/01 15:46:12.82
すのいまんって グアルディオラみたいな顔してるね。

501:デフォルトの名無しさん
12/02/01 20:49:46.05
ruby on railsに似たFWってあります?

502:デフォルトの名無しさん
12/02/01 21:28:18.68
市原警察署生活安全課の創価警官名言集

「俺のおかげで家から出れなくした。俺の手柄だ!」

「昼間は市役所のパトロール隊を使う。夜は消防団を使う。」

防犯パトロールと称する近所の創価学会員が
中学生を口実にした何年にも渡る誹謗中傷行為や人権侵害行為について
市原警察署生活安全課の創価警官の指導でやってあげているんだと発言したことについて
「指導じゃない、パトロールをお願いしてるだけだ。俺の責任じゃない!」

いくら創価学会員が集団で誹謗中傷を繰り返しても
調べれば何の前科もない事くらいすぐわかるのに
創価学会員の発言に根拠のない点については完全無視

帰化人の創価学会員が当たり前のように警官になれてしまう狂った世の中



503:デフォルトの名無しさん
12/02/03 08:42:57.25
諸君、ホットな話題は?

504:デフォルトの名無しさん
12/02/03 15:52:10.78
相変わらず俺がモナド理解できない圏に付いて

505:デフォルトの名無しさん
12/02/03 17:33:55.88
圏論に懐疑的な人の方が攻略が早い

506:デフォルトの名無しさん
12/02/03 18:48:41.28
アローはモナドにできる事が全てできます。
アローにできるがモナドにできない事もあります。
アローにはモナド則のような余計な規則がありません。
アローはモナドより理解しやすく圏論を知らなくても理解できます。
だからアローがあればモナドは不要です。

モナドは今となっては無駄に挫折者を増やす過去の遺物です。
Haskellはモナドを全廃しアローに置き換えるべきだと思います。

507:デフォルトの名無しさん
12/02/03 19:26:50.37
>>506
> アローにはモナド則のような余計な規則がありません。

モナド則は「余計」でアロー則は「余計ではない」理由が分からない

もっとちゃんと説明して欲しい

508:デフォルトの名無しさん
12/02/03 19:34:54.82
>>406
> アローはモナドにできる事が全てできます。

この理屈だと、Control.Applicative なども要らない
と言っているように感じる

しかし、実現したい計算と式に関して、
必要十分な機能は何かと考えることは大事だと私は思う
なぜなら、そう考える過程で計算と式が洗練されていくからだ

何でもかんでもアローでプログラムするのは、
プログラミングを不必要に複雑にする事に繋がりかねない

509:デフォルトの名無しさん
12/02/03 19:39:08.83
>506
>アローはモナドにできる事が全てできます。
>アローにできるがモナドにできない事もあります。
逆じゃね

510:デフォルトの名無しさん
12/02/03 22:50:53.19
アローの良質な入門サイトを紹介して下さい(勿論日本語の)

511:デフォルトの名無しさん
12/02/03 23:22:13.48
アロー演算子ならまかせろ!

512:餃子チョコレート ◆8X2XSCHEME
12/02/03 23:25:47.33
>>510
こういうのはどう?
URLリンク(d.hatena.ne.jp)

513:デフォルトの名無しさん
12/02/04 00:05:18.95
>>506
Arrowの心
URLリンク(d.hatena.ne.jp)
>Monadと同様にArrowにもArrow則という規則があります。
> 1. (a >>> b) >>> c = a >>> (b >>> c)
> 2. arr (g.f) = arr f >>> arr g
> 3. arr id >>> a = a = a >>> arr id
> 4. first a >>> arr pi1 = arr pi1 >>> a
> 5. first a >>> arr (id X f) = arr (id X f) >>> first a
> 6. first a >>> arr alpha = arr alpha >>> first (first a)
> 7. first (arr f) = arr (f X id)
> 8. first (a >>> b) = first a >>> first b

514:デフォルトの名無しさん
12/02/04 13:28:24.89
>>512
読みました\(^O^)/

515:デフォルトの名無しさん
12/02/04 17:10:59.19
要約すると「Arrow はパズル」。


516:デフォルトの名無しさん
12/02/04 17:41:35.25
> とりあえずfirstについてのルール4,5,6,7,8は無視します。
ワロタ

517:デフォルトの名無しさん
12/02/05 10:47:39.79
ghciで階乗の関数factを定義しようとしてるのですが、以下のようにすると
Prelude> let fact 0 = 1
Prelude> let fact n = n * fact (n - 1)
Prelude>
先週まではうまく行ってたのに、急になぜかうまくいかなくなりました。
Prelude> fact 10
^CInterrupted.
Prelude>
fact 10とかやると永遠に返って来ません。
どうもlet fact 0 = 1のあとにlet fact n = n * fact(n-1)とやるとfactの定義が上書きされてる
みたいなのですが、何か間違ってるでしょうか?


518:デフォルトの名無しさん
12/02/05 12:44:07.59
>>517
ghci上ではこうやるといいです

let fact 0 = 1; fact n = n * fact (n-1)

先週か今週にかけて ghc のバージョンアップをしたのでは?
ghciの仕様が変わったかどうか詳細は知らないので、原因は違うかもですが

519:デフォルトの名無しさん
12/02/05 13:16:48.53
>>518
ありがとうございました。動きました。
先週までは
Prelude> let func1 'a' = "aaa"
Prelude> let func1 'b' = "bbb"
こう書けてたと思うんですが、自信がなくなってきました。上のも、こう書けば動きました。
Prelude> let func1 'a'="aaa"; func1 'b'="bbb"
ありがとうございました。


520:デフォルトの名無しさん
12/02/06 18:39:55.29
HaskellはHTMLに<?haskel ?>のように
埋め込めますか?

521:デフォルトの名無しさん
12/02/06 18:43:44.18
>>520
埋め込んだらええやん

それを解釈して正式な HTML や JavaScript なんかに変換する
サーバーアプリに通せばええよ

522:デフォルトの名無しさん
12/02/06 18:51:15.58
なんちゅう名前のサーバアプリがええんですか?

523:デフォルトの名無しさん
12/02/06 19:16:46.10
>>522
そんなん自分で作るんちゃうんかいな

探したって無駄やさかい

524:デフォルトの名無しさん
12/02/06 19:32:44.58
>>523
ホンマですか? えらい難儀な話ですけど、しゃーないですね。
スレ汚しすんませんでした。

525:デフォルトの名無しさん
12/02/06 20:25:45.57
>>523
てげよだきー

526:デフォルトの名無しさん
12/02/07 07:07:30.44
んじちゃーぴら

527:デフォルトの名無しさん
12/02/07 07:48:14.32
a_1 = a_2 = 1, a_n+2 = a_n+1 + a_n

a_9 = a_8 + a_7
  = (a_7 + a_6) + a_7

でa_7をグラフ簡約してくれるようにするにはどうしますか?

まさか a_7 を2度計算するなんて事になったら
土砂降りの中、滑って転んだ野良犬のような惨めに打ちのめされた気分になります

  = (a_7 + a_6) + [a_6 + a_5]_7
  = (a_7 + [a_5 + a_4]_6) + [a_6 + a_5]_7
  = (a_7 + [a_5 + a_4]_6) + [a_6 + [a_4 + a_3]_5]_7
  = (a_7 + [a_5 + [a_3 + a_2]_4]_6) + [a_6 + [a_4 + a_3]_5]_7
  = (a_7 + [a_5 + [a_3 + a_2]_4]_6) + [a_6 + [a_4 + [a_2 + a_1]_3]_5]_7
  = (a_7 + [a_5 + [2 + 1]_4]_6) + [a_6 + [a_4 + [2]_3]_5]_7
  = (a_7 + [a_5 + [3]_4]_6) + [a_6 + [3 + [2]_3]_5]_7
  = (a_7 + [5 + [3]_4]_6) + [a_6 + [5]_5]_7
  = (a_7 + [8]_6) + [8 + [5]_5]_7
  = (13 + [8]_6) + [13]_7
  = 34

ってイメージで

528:デフォルトの名無しさん
12/02/07 18:48:44.70
>>527
何らかの形で共有を明示するしかない
たとえば
fib = 1 : 1 : zipWith (+) fib (tail fib)

529:デフォルトの名無しさん
12/02/07 21:57:38.51
>>528
フィボナッチ以外でも適用できる汎用的なノウハウが欲しいです
寧ろ数列計算よりシミュレーション的な
将棋の次の一手の探索みたいな

530:デフォルトの名無しさん
12/02/07 22:02:40.24
・処理するには新しい処理が芋蔓式に出現する
・それらの多くが頻繁に共通にあらわれる・共通処理は省かないと総処理は天文学的オーダーで膨れ上がる


こういうケースの汎用指針が欲しいです

531:デフォルトの名無しさん
12/02/07 22:07:23.01
DPを自動でやりたいように見えた

532:デフォルトの名無しさん
12/02/07 22:09:06.55
>>530
メモ化ね
汎用指針は、計算済みの値を捨てないで保存しておくこと
IOとかStateモナド上で状態にして引き回してもいいし、
>>528みたいに、全部の値を含む(場合によっては無限の)データ構造を定義してもいい

533:デフォルトの名無しさん
12/02/08 07:20:52.45
>>531
「芋蔓式に出現する」の意味がよく分からないけど、新しい式を書き加えてなんどもコーディングするっていうことなら、トップレベルに定義していけばよいんじゃないの?

コーディングを繰り返さないなら、>>532のいうようにメモ化を求めているんだろうけど、将棋の次の一手とかメモ化したら空間オーダが爆発しそうだな。
それで解決できるなら、将棋の決して負けない手順がすでに明らかになっているだろうし。
そのレベルのことをどうしてもやりたいなら金に糸目を付けず並列クラスタを作るしかないんじゃないの?

534:デフォルトの名無しさん
12/02/08 07:50:15.51
「Stringはオワコン。これからはText」って言われてるのを見て
Data.Text を使おうとしたけれど、なんで index が O(n) なの?
中身はただの配列だと思ってたのに。
URLリンク(hackage.haskell.org)



535:デフォルトの名無しさん
12/02/08 09:20:34.12
データはコピーしないで、リストでデータの在処を持ってるんでしょ。
lastがO(1)だからケツも押させてるんだと思う。

536:デフォルトの名無しさん
12/02/08 11:41:41.19
>>535
ありがとう。

ソースをざっと見てみたら、配列・オフセット・長さの組を使っているようだっ
た。単なる配列じゃないのは、部分文字列(tail とかで)でコピーしなくていい
ようにするためらしい。

で、index が遅いのは、Unicode のサロゲートがらみみたい。index s n の n
が文字数なので、サロゲートがあると配列のインデックスとずれてしまうせい
で、先頭か最後から順番に数えてるようだった。length が O(n) なのも、たぶ
んそれが理由。

ちょろっと眺めただけなので、まちがってるかも。

とりあえず String より遅くはなさそうなので、もうちょっと試してみます。


537:デフォルトの名無しさん
12/02/08 12:05:29.10
とにかくでかいデータ用だぜ。

538:デフォルトの名無しさん
12/02/08 12:10:04.92
時代はUTF32

539:デフォルトの名無しさん
12/02/08 12:35:16.38
UTF48

540:デフォルトの名無しさん
12/02/08 13:42:13.86
>>515
じゃあパズルをとこうぜ。
URLリンク(www.amazon.co.jp)
URLリンク(www.amazon.co.jp)

541:デフォルトの名無しさん
12/02/08 18:37:49.70
>>539
warota

542:デフォルトの名無しさん
12/02/10 21:18:58.47
QuickCheck って Monad もテストできるのずっと気づかなかった

543:デフォルトの名無しさん
12/02/10 23:30:34.09
本屋に行ったけど、RWHしかなかった
人気ないのかな…

544:デフォルトの名無しさん
12/02/11 02:30:53.27
>>543
人気の定義による。

・プログラマー人口内のシェア?
→世間のビジネスの9割以上は単純な事務作業なので、 そういう処理を書ける言語はHaskell以外に沢山ある。
ちなみに、書店はシェア重視。

・ある問題領域で解決したい課題を持つ者にとって、ロジックを実装しやすいか?
→自分と同様の問題領域の人を探したほうがいい。

545:デフォルトの名無しさん
12/02/11 08:27:54.18
>>543
RWHの和訳って前半部分がいまいちわかりにくいのが残念。
また、あのままでGHC7以後で動かそうとすると、ちょっと面倒なところ
が出てる。だから、改訂版に期待したいんだがな。

546:デフォルトの名無しさん
12/02/11 08:30:21.86
・Haskell高速化テクニック
なんて本がでないかな?


547:デフォルトの名無しさん
12/02/11 08:31:18.34
言いだしっぺの法則

548:デフォルトの名無しさん
12/02/11 08:40:30.32
オライリーが投資を回収できてれば次も期待できると思うが、どうなんだかね

549:デフォルトの名無しさん
12/02/11 09:05:15.98
yesod本がでるくらいだから、RWHは収益が上がってるんじゃないかと?
>>547 残念だけど、教えて欲しい立場。人にチューニングを語れるほどじゃないし。

550:デフォルトの名無しさん
12/02/11 09:23:04.02
Haskell wikiのPerformanceの項とかmkothaさんの記事
ghcのドキュメント
ghcのプロファイリング機能とかcriterionパッケージ
thread scope

最終的には諦めてC++/Asmで書く

551:デフォルトの名無しさん
12/02/11 12:12:58.97
クリテリオンんて何かワクワクする語感だな
アニメでいうとロボものだろう

552:デフォルトの名無しさん
12/02/11 12:46:57.36
クライテリオンな

まぁ別にどっちでもいいことだけど

553:デフォルトの名無しさん
12/02/11 13:56:27.61
超聖判規クライテリヲン

554:デフォルトの名無しさん
12/02/11 19:24:57.36
あ、関節の病気か。

555:デフォルトの名無しさん
12/02/11 23:32:33.40
2日に GHC のバージョンが 7.2.2 から 7.4.1 に上がってたのか

ghci 上で data や instance なんかの宣言ができるようになってた
これは便利

それはそうと、さっさと実行時に利用コア数を変えられるようにしてほしいものだ

556:デフォルトの名無しさん
12/02/11 23:50:35.15
setNumCapabilities
増やせるだけで減らせないみたいだけど

557:デフォルトの名無しさん
12/02/11 23:54:08.17
we recommend installing the Haskell Platform instead of GHC. The
current Haskell Platform release includes a recent GHC release as well
 as some other tools (such as cabal), and a larger set of libraries
that are known to work together.

と書いてるからさ、5月まで待ったほうがいいんじゃない? <7.4.1

558:デフォルトの名無しさん
12/02/11 23:59:10.81
GHCの代わりにHaskell Platformをインストールするのを薦めとくわ。いまの
Haskell Platformは最近のGHCを含んでいて、おまけに、他のツール(cabalと
かね。)も動くし、よく使われてるライブラリも動くからさ。

だとさ、と意訳しとく。

559:デフォルトの名無しさん
12/02/12 00:00:24.87
既存プロジェクトの移行はライブラリが7.4に対応するまで待つとしても、
普段は最新版使った方が楽しい

560:デフォルトの名無しさん
12/02/12 00:03:51.27
Debian系統だとHaskell Platformは単なる仮想パッケージ。

561:デフォルトの名無しさん
12/02/12 00:06:35.18
>>559
まあ、こなれた人ならそうかもしれない。でも、ここって、いろんな人が
いるから、一応書いといた。こなれた人ならトラブルに出会っても、解決
できるだろうし、それが楽しいもんな。

URLリンク(groups.google.com)
でも、しんさんがリリースのメールに注意書きがされているけどね。

562:デフォルトの名無しさん
12/02/12 08:01:47.18
someRecord{someField = f $ someField someRecord}

haskellのレコード構文って何でこんなきもちわるいの
フィールド一つ書き換えただけの新しいレコードが欲しいだけなのに

563:デフォルトの名無しさん
12/02/12 08:17:24.52
ご覧下さい
このクランケの症例では

・碌に調べもしない
・煽る事で住人達に答えさせようとしている

点が伺えます

これらは怠慢横柄病患者に共通に見られるのです

564:デフォルトの名無しさん
12/02/12 08:37:41.32
バレたか・・・
いやまあ、自分で調べなかったわけでもないんだけどな
ほぼ無理なのは分かってる

565:デフォルトの名無しさん
12/02/12 08:40:12.60
本当の地獄はレコードをネストさせてからだ…

566:デフォルトの名無しさん
12/02/12 11:11:24.92
>>562
どういう書き方ができると良かったの?

567:デフォルトの名無しさん
12/02/12 11:22:02.57
>>556
増加だけでもできるようになったのか
リリースノートを斜め読みしてたから見逃してた

568:デフォルトの名無しさん
12/02/12 11:34:11.27
ネスとされたレコードの書き換えはdata-accessorとかlenseとか使うと少しは楽になるけど
これパフォーマンスどうなるんだろうという不安が出てくる

569:デフォルトの名無しさん
12/02/12 11:35:43.98
>>568
神に従え


570:デフォルトの名無しさん
12/02/12 12:17:15.85
>>566
SomeRecordとSomeFieldを二回も書きたくないというか
フィールドと同名のgetterを自動生成するような動きを許容したのなら
もっとはっちゃけて欲しかったというか
テンプレート? テンプレートなぁ・・・

571:デフォルトの名無しさん
12/02/12 12:29:24.18
TemplateHaskellの有用性はlispが示している

572:デフォルトの名無しさん
12/02/12 13:23:20.06
>>570
そうは言っても、「汎用的にするなら」 少なくとも

1. 何のデータ型の(値の)
2. 何のフィールドを
3. どう変えるのかを

この3つのは何らかの形で指定する必要があると思うが

573:572
12/02/12 13:31:17.15
>>570
すまん、不満点をちょっと勘違いしてたみたいだ

こういうことか

someRecord { someField = f $ someField someRecord }

{} 前の someRecord の部分が型構築子じゃなく値構築子の場合、
f $ someField someRecord の someRecord 部分は明白だから省略可能

こうなれば、幾分スッキリするな

574:デフォルトの名無しさん
12/02/12 15:04:59.49
Cabal でライブラリをインストールする時、
オプションで library-profiling を有効にすると、
そのライブラリもプロファイリングの対象にできるよね

これって、プロファイリングしないで普通に使う時は
遅くなったりしない?

575:デフォルトの名無しさん
12/02/12 15:11:00.59
-pを使うとパッケージを二通りコンパイルする
ので遅くならない

576:デフォルトの名無しさん
12/02/12 15:31:06.20
>>575
そっか、安心した
ありがと

577:デフォルトの名無しさん
12/02/12 19:23:37.68
Yampa の par 関数の型について質問です。
(他のパラレル系関数もですが、代表して par を選びました)

par :: Functor col => (forall sf. a -> col sf -> col (b, sf)) -> col (SF b c) -> SF a (col c)

このルーチン関数の sf という型変数には、SF b c 以外入ることは無いと思うのですが、
単純に a -> col (SF a b) -> col (b, SF a b) という型では何がいけなかったのでしょうか

578:デフォルトの名無しさん
12/02/12 21:52:55.77
Cabal で --enable-documentation とやっていっしょにインストールされるドキュメントに、
ソースコードへのリンクが貼られるようにする方法はないのでしょうか?

HackageDB のサイトで見られるドキュメントみたいにしたいです

579:デフォルトの名無しさん
12/02/13 10:41:10.37
>>577
スライドとか論文だと確かOpacity(透過性?)のためとか書いてあって、
俺も正確な意味はよくわからなかったんだけど、
SFを書き換えられるような関数を渡せるのを防止してるんじゃないかな。
route a xs = [(a, identity)]
みたいな、コレクションの中身を無視して出所不明のSFにしちゃうような。

580:デフォルトの名無しさん
12/02/16 05:11:31.94
F#を始めたのだが、モナドで行き詰まっている。
F#の本にはモナドのことが書いていない。
で、ネットでモナドのことを収集すると、ハスケルのがほとんど。
F#での説明もあるが、なんか解りづらい。

で、モナドって何ですか?
関数型プログラミングをやるにはモナドが必須ですか?

どなたか教えてください _o_

581:580
12/02/16 05:15:46.89
ちなみに数学科出身ですが、圏論は知りません。
習った覚えがありませんし、仮に習っていても記憶にないのだから、習っていないのと同じです。


582:デフォルトの名無しさん
12/02/16 05:48:37.15
モナドはモナド則そのもの。
使い方としてはモナド則を頭に入れてからListモナドとStateモナドを理解すれば後は大体類推が利く。
F#でどうなのかは知らないが、少なくともHaskellで何か書こうと思ったらモナドは必須。
まあ「モナドとは何か」みたいな話は過去スレ遡ればいくらでも出てくるよ。

583:デフォルトの名無しさん
12/02/16 08:10:51.47
わかればわかるけど、モナドはモナド則そのものってのが禅問答みたいで
わかりにくいんだよなぁ。。

Haskellのクラスは、C++でいう抽象クラス見たいなもので、
Haskellのモナドがクラスでどう定義されてるか調べていけば、
意味はわからなくても、使い方はわかると思うよ。

モナドの意味は使っている内に、なんとなくわかるようになる、、、と思う。

584:デフォルトの名無しさん
12/02/16 09:19:10.08
コンポーネントのようでコンポーネントでない
象のようで象のようでない
さてはモナドって南京弾簾だろ!

585:デフォルトの名無しさん
12/02/16 09:37:41.55
Haskell 最大の失敗はモナドにモナドという名前をつけたことにある。
もっと「もこもこ」みたいな可愛い名前にすれば大流行していた。
とか講演でいってたな。


586:デフォルトの名無しさん
12/02/16 09:48:34.02
名前はモナドのまま、バインド演算子を ( ´∀`)みたいなのにすれば良かったのではなかろうか

587:デフォルトの名無しさん
12/02/16 09:51:36.68
ガンダムで頼む

588:デフォルトの名無しさん
12/02/16 10:16:54.54
>>585
そのソースはどこよ?w

589:デフォルトの名無しさん
12/02/16 13:28:49.11
>>588

元ネタはこれのはず。

Wearing the hair shirt: a retrospective on Haskell (2003)
Simon Peyton Jones, invited talk at POPL 2003.
URLリンク(research.microsoft.com)

Our biggest mistake
Using the scary term "monad" rather than "warm fuzzy thing"


590:デフォルトの名無しさん
12/02/16 14:37:03.09
2011年版はビデオで見られる。ちょっと重いけれど。
Escape from the Ivory Tower: The Haskell Journey, from 1990 to 2011
URLリンク(yow.eventer.com)

簡単だけど32分あたりに "warm fuzzy thing" が出てくる。

各銀行が秘密の Haskell 部隊を雇ってるって話はどこまで本当なんだろう。


591:デフォルトの名無しさん
12/02/16 15:37:45.12
>>583
なんでこのなものが要るのか直感的に分からないってこと?

592:デフォルトの名無しさん
12/02/16 15:56:24.13
>>585
そして処理が一本道だから
もこもこで一本道

略して もこみち とかどうよ?

593:デフォルトの名無しさん
12/02/16 16:21:24.02
>>583
Haskellの型クラスはC++の抽象クラスとは全く違うよ。
オブジェクト指向の考え方は捨てるべき。

594:デフォルトの名無しさん
12/02/16 18:14:54.42
Haskellとオブジェクト指向は根本的に違うから例えて考えるのは実際の処理挙動ぐらいにしたほうが……

595:デフォルトの名無しさん
12/02/16 18:27:40.48
C++にはクラスという機能を用いて現実世界の概念を抽象化することに成功し、直感的な設計・実装が行えるようになった
Haskellでは、どのようなパラダイムがこれから出てくるのか
私はそれが楽しみでならないのです
って去年死んだおじいちゃんが死ぬ間際に言ってた

596:デフォルトの名無しさん
12/02/16 18:49:29.40
ぷうぷう!

597:デフォルトの名無しさん
12/02/16 19:05:35.61
もこもことかモコナとかそういうかわいいのはいらない
モサドにしよう

598:デフォルトの名無しさん
12/02/16 19:24:01.77
>>595
Haskellは遅延評価という機能を用いて現実世界の手順を隠蔽することに成功し、
宣言的な設計・実装が行えるようになりました。
しかしHaskellは関数型言語からは踏み出さないだろうから、新しいパラダイムは
Ozのようなマルチパラダイム言語に期待すべきだろうと思えてならないのです。
って友達がさっき言ってた。

コンピュータプログラミングの概念・技法・モデル
スレリンク(tech板)

599:デフォルトの名無しさん
12/02/16 19:27:51.75
Ozはオワlan

600:餃子チョコレート ◆8X2XSCHEME
12/02/16 20:52:04.09
うまいな。
一瞬「終ったランゲージ」と思わせといて実は「終わらん」というダブルミーニングですね!!

601:デフォルトの名無しさん
12/02/16 22:13:47.28
>>593
そう?
「Learn You a Haskell for Great Good!」には、JavaのInterfaceみたいなのと
考えたほうがいいって書いてるけど。
全く違うっていうならどう考えればいいか説明してほしいな。



602:デフォルトの名無しさん
12/02/16 22:27:34.65
>>591
最初、(>>=)はただ関数に引数にして渡すだけじゃないか、なんで必要なんだとか思ってた。
他のもなんでこんなのが必要か理解できなかったよ。

変な型修飾付けるせいで、型が違うって怒られるし。

でもそうやって好き勝手書けないようにするのが狙いなんだな。

603:デフォルトの名無しさん
12/02/16 22:46:41.67
デザインパターンみたいなもの、でいいと思うけどな > モナド

604:デフォルトの名無しさん
12/02/16 22:56:34.58
私は >>593 ではないのですが、逆に訊きたいです

Haskell の型クラスと Java のインターフェイスにおいて、
考え方の共通点とは何でしょうか

それは、コンパイル時にどう解釈されるかというレベルの共通点でしょうか
それとも、アプリケーションを作る上での指針となるくらいのレベルの共通点でしょうか

605:604
12/02/16 22:57:13.58
>>604
すいません、>>601 に対しての質問です

606:デフォルトの名無しさん
12/02/17 03:06:37.40
Haskellのclassはplatformに改名しろ

607:デフォルトの名無しさん
12/02/17 04:24:56.80
型を集合だと考えれば型クラスって命名は自然

608:デフォルトの名無しさん
12/02/17 04:41:03.84
型(type)のメタ概念として類(class)という名前を採用することは間違っていない
ただし、これだけオブジェクト指向の概念が普及しているのが現実なのだから、
それを配慮した命名が望ましかった(かもしれない)ということ

これをHaskellの傲慢さと見るか、それとも数学的に正しい命名であると見るかは
判断が分かれるところ

609:デフォルトの名無しさん
12/02/17 04:50:13.16
オブジェクト指向のclassが類と無関係だと思ってるっつーか、
類をモデルにしているのはtype classだけだとか思ってるところが
Haskellerの傲慢さじゃないの?

610:デフォルトの名無しさん
12/02/17 05:12:11.76
simula(I,67) URLリンク(staff.um.edu.mt)
smalltalk(80) URLリンク(web.cecs.pdx.edu)
これ参考にCからC++とObjCができたのか。

611:デフォルトの名無しさん
12/02/17 06:49:42.48
>>609
オブジェクト指向のclassって命名にケチつけてるなら
Haskellerは傲慢だけど、そうじゃないよね?

612:デフォルトの名無しさん
12/02/17 07:36:36.25
オーバーロードは必要でオーバーライドは不要だと思ってるところが傲慢だ

613:デフォルトの名無しさん
12/02/17 09:25:13.67
>>580
ここは読んだか?
URLリンク(www4.atwiki.jp)

614:デフォルトの名無しさん
12/02/17 09:28:48.05
>>550
Johan TibellのHaskell Performance Patterns talkのスライドも
このリストに追加の資料になりそう。

615:デフォルトの名無しさん
12/02/17 11:31:01.99
>>604
全く同じとまでは言わないけど、
Haskellのtype ≒ Javaのclass
と考えたときに、
Javaのinterfaceがclassにまたがって横断的に制約を作れるというところが、
Haskellの型クラスがデータ型を横断して共通の「クラス」を作れるところ
と似てるって言ってるんじゃないの。
とりあえず最初の入り口から何でも違う違う言ってたら、誰もHaskell始められないよ。


616:デフォルトの名無しさん
12/02/17 11:43:00.28
>>615
このスレを見て面白そうなので僕は今日から始めました。

617:デフォルトの名無しさん
12/02/17 12:42:29.71
>>615
ということは、それはコンパイル時の解釈の問題ですよね

>>593
> オブジェクト指向の考え方は捨てるべき
と言っており、これはアプリケーションを作る指針となる考え方において、
抽象クラスとは違うことを言っているように思えます

もしそうなら、それに対する反論としての >>593 は的外れだと思います

>>583 も、わかればわかるけど、モナドはモナド則そのものは解りにくいと言ってることから、
入門レベル(最初の入り口)は通り過ぎているものと思われます。


> とりあえず最初の入り口から何でも違う違う言ってたら、誰もHaskell始められないよ。

それはそうですが、それとは別問題として、話が噛み合っていないような気がします

618:はちみつ餃子 ◆8X2XSCHEME
12/02/17 13:03:38.71
俺もあんまり「××のようなもの」っていう解釈はしない方がいいと思ってる。
部分的に機能がかぶるだけで類似性を見出していたのではそれに引き摺られて根本的なパラダイムの理解に進み難い。

619:デフォルトの名無しさん
12/02/17 13:25:22.45
type classってオーバーロードと型推論を両立するための妥協だから
パラダイムみたいな高尚な概念じゃないよ

620:デフォルトの名無しさん
12/02/17 13:34:40.12
そんなこと言ったらOOPにだってパラダイムなんて高尚なもん
一つも無ぇっつーの

621:615
12/02/17 14:08:40.22
>>617
話の流れ見てなかった。すまんかった。
だからケンカしないで。

622:デフォルトの名無しさん
12/02/17 14:17:39.16
>>617
横レスだけど、

・オブジェクト指向のクラスもHaskellの型クラスも
 「抽象データ型」の実現という意味では似ている(>>615)
・オブジェクト指向の「インヘリタンス」とHaskellの「アドホック型多相」とは
 型システム理論という意味では全く違う(>>593)

ということじゃないのかな?
各用語の意味は、自分で調べてね

623:デフォルトの名無しさん
12/02/17 14:31:40.54
>>622
OOPの「継承」は部分型多相では?

624:デフォルトの名無しさん
12/02/17 14:34:40.69
>>623
オーバーライトや疑似変数selfなんてのは、部分型多相には存在しない概念/理論

625:デフォルトの名無しさん
12/02/17 14:46:11.83
>>623
なるほど。型理論勉強します。

626:625
12/02/17 14:46:38.91
>>624 だった

627:デフォルトの名無しさん
12/02/17 14:58:14.86
>>619
型クラスにはアドホック型多相という理論的基盤があるから、
それはいわゆる「高尚」と表現してもかまわないんじゃまいかと思う

>>620
OOPの継承というのは直感的かつ曖昧なもので、その足場は非常に不安定
だからオブジェクト指向について10人に尋ねれば、10人それぞれが異なった解釈を返す
そんな代物を「高尚」とは、とても呼べないんじゃまいかと思う

628:627
12/02/17 15:10:40.81
訂正

X: OOPの継承というのは....
O: OOPというのは....

629:デフォルトの名無しさん
12/02/17 15:18:03.49
>>624
概念/理論は存在したり存在しなかったりするんだな・・・
それなら概念/理論を教えるよりも実装を教える方が良い

630:デフォルトの名無しさん
12/02/17 15:22:36.71
例えばC++で言うところのオブジェクト指向とは
・情報隠蔽
・継承
・ポリモーフィズム
でした

631:デフォルトの名無しさん
12/02/17 15:26:42.34
オーバーロードをアドホック多相と言いかえると何か凄そうに見えるテクニックはテストに出ます

632:デフォルトの名無しさん
12/02/17 15:39:17.02
>>629
>概念/理論は存在したり存在しなかったりするんだな・・・

え、オーバーライトや継承の概念を含む、いわゆる「継承の型システム」に関する理論は、
いくつか存在しているよ
足りないのは動的なメソッド結合(ダックタイピング)や動的な型付け(メタプログラミング)の理論

そんな完成した静的型付けな型システムの一つを実装したのがObjective-Caml
ただし、(Objective-CがOOとCのハイブリッド言語であるように)
部分型多相と継承は理論的に全く違うから、両者のハイブリッドになっている
結果として、残念ながら「関数型パラダイムにおけるオブジェクト指向」という理想には程遠い

633:632
12/02/17 15:41:17.07
また訂正

X: オーバーライトや継承の概念を含む、....
X: オーバーライトや疑似変数selfの概念を含む、....

634:はちみつ餃子 ◆8X2XSCHEME
12/02/17 15:48:26.21
>>633
また訂正ですね!!

635:632
12/02/17 16:17:42.90
>>634
...orz

すぐに分かってくれたようだから、あえて訂正しないw

>>631
MLやHaskellでは、JavaやC++のようなNullPointerExceptionやBusErrorは発生しない
型に関するミスは、コンパイル時にすべて検出できる
それが、理論的背景のある型システムの「凄さ」だと言える

次のテストに出すかもしれないから、よく復讐しておくように

636:デフォルトの名無しさん
12/02/17 16:40:57.39
別に凄くない
むしろ、すべてに責任をもつことはできないから責任を限定する理論が必要になる
型に関するミス以外は管轄外だし
プログラマーが勝手に Nothing とか [] を使うのは自己責任

637:デフォルトの名無しさん
12/02/17 16:47:11.46
言語の中でNullを扱わなくなっただけで、Nullみたいな値の濫用の余地は残るわけですよね。
昔のCOBOLはNULLが扱えなくて0000や9999などの値で成功失敗とか表現していましたし、そういうシステムはかなり多いと聞いています。
つまり、NULL無いんなら0000や9999でいいやと思うような人には型システムなんて意味ないんじゃないでしょうか?


638:デフォルトの名無しさん
12/02/17 16:56:36.58
>>611
他パラダイムや他言語を矮小化する一方で、
「無秩序でいい加減な」という意味のアドホック多相を
あたかも高尚なものであるかのように
誇張しているだけだから、傲慢じゃなくて
滑稽だね。

639:デフォルトの名無しさん
12/02/17 17:06:52.05
ad hoc
 adv., adj. (特に)このために[の], 特別に[の], この場限りで[の], その場限りで[の].
                        研究社 新英和大辞典 第6版

640:デフォルトの名無しさん
12/02/17 17:20:15.57
URLリンク(www.youtube.com)

641:デフォルトの名無しさん
12/02/17 17:21:05.17
カズヤマモトサンかっけー

642:デフォルトの名無しさん
12/02/17 18:09:29.51
この流れで質問させてください
型クラスってのは代数的構造のことではないんでしょうか?

643:デフォルトの名無しさん
12/02/17 18:48:32.83
>>642
そんなようなものだけどもうちょっと一般的
C aというインスタンスのメソッドの戻り値の型はa以外になり得る
OrdとかShowとか

644:デフォルトの名無しさん
12/02/17 18:57:33.81
>>635
ヌルポは値に起因するバグで、型システムによる安全性の保証外なのはML系でも同じだよ。
MaybeはまんまC#のnullable<T>だし。
Haskellはパターンマッチでパターンを網羅してないとちゃんと警告出してくれたり、
Maybeモナドみたいな明示的にチェックを書かなくても済む仕組みその他諸々のおかげでバグりにくいって話で、
コンパイルで検出出来てるわけじゃないし、発生しないわけでもないよ。

645:デフォルトの名無しさん
12/02/17 19:12:32.81
>>642
型クラスもデータ型もメモリ上のビットも代数的構造

646:デフォルトの名無しさん
12/02/17 19:24:43.41
NullPointerExceptionはバグなの?

647:デフォルトの名無しさん
12/02/17 19:29:54.49
>>644
Maybeはぬるぽがっされないような、、、

648:デフォルトの名無しさん
12/02/17 19:43:26.86
>>645
そういう文脈で代数的構造と言った場合の「代数的」とはどういうものですか?

649:デフォルトの名無しさん
12/02/17 20:02:36.22
>>648
代入可能なこと
定数以外は代数的構造

650:デフォルトの名無しさん
12/02/17 20:55:05.10
>>647
トリビアルな例だけど、常にJustな事が期待されてる変数alwaysJust :: Maybe aがあったとして、
1)
case alwaysJust of --これは警告がでるけど
 Just x -> x

2)
let (Just x) = alwaysJust in x -- こんなドタコなコードは書かないけど…

3)
-- fooの使用者からは定義かドキュメントを見ない限り、例外が上がってくる可能性がある事は知りようがない
foo :: a -> a
foo v = fromJust $ do -- fromJustってどういうケースで使うんだろか…。
 x <- alwaysJust
 v' <- Just v
 ...
 return v'

もし、alwaysJustがバグっててNothingだったら、上の例は全部例外あげてくる。
特に3番目みたいな外からは一見安全に見える型の関数でも、ガッされない絶対の保証があるわけでも、検出できるわけでもないよ。
(1番目以外は警告すらでないし)

Maybeからそれると、Preludeの関数でもListのheadとか(!!)とか、Enumのsucc、predとかreadやArrayとか、
プログラマがちゃんと保証しなきゃいけない関数も結構あるし。

651:デフォルトの名無しさん
12/02/17 21:29:13.08
Maybeからそれると、Intも危険だよね
オーバーフローして意図しない挙動をする危険性があるから
プログラマがちゃんと保証(ry

652:デフォルトの名無しさん
12/02/17 21:31:32.72
RWHを買ってきました
あしたRWHを一日かけて読み切ります
何か注意点とかありますか

653:デフォルトの名無しさん
12/02/17 21:35:16.99
急いで読まない

654:デフォルトの名無しさん
12/02/17 21:59:05.59
コードを写経して動かなくても文句言わない

655:デフォルトの名無しさん
12/02/17 22:12:05.67
なんか、ものすんごい勢いでレスついてるね。
みんな暇か?

656:デフォルトの名無しさん
12/02/17 22:15:37.70
詰まったり解らなかったり動かなかったら本家(>>5の上)のコメントなんかも参照
一日で読み切れなくても泣かない投げない

657:デフォルトの名無しさん
12/02/17 22:19:09.47
>>652
最初からまじめに読んでいくと冗長度が高くて飽きる。飛ばして途中から見ると何言ってるのか分からない。
昆虫本には良くあることです

658:デフォルトの名無しさん
12/02/17 22:28:48.44
今 GHC 7.4.1 の環境です

デュアルコアのCPUを使ってて、GHC の RTS オプション -N2 で、
2スレッドが平行して動くことは確認できました

今 Intel のハイパースレッディング(HT)機能を持つ CPU に変更する検討をしていますが、
GHC のマルチコア機能はHTに対応するのでしょうか

コア数を返す関数がHTを考慮した論理コア数を返す事はリリースノートで確認しましたが、
実際に平行して動くスレッドの数として正しく機能するかという質問です

つまり、例えばコア数2のHT機能を持つCPUで -N4 を指定すれば、
ちゃんと4つのスレッドが平行して動くのでしょうか

659:デフォルトの名無しさん
12/02/17 22:30:08.58
RWH一日は無理だろ

660:デフォルトの名無しさん
12/02/17 23:04:02.43
>>658
>GHC のマルチコア機能はHTに対応するのでしょうか => Yes
>ちゃんと4つのスレッドが平行して動くのでしょうか => No
ちゃんとの意味にもよると思いますが
詳しくはwikipediaを


661:デフォルトの名無しさん
12/02/17 23:25:23.88
>>660
> ちゃんとの意味にもよると思いますが

例えば RTSオプションで -s を指定して実行して得られる情報において、
コア数2のCPUよりコア数2HTのCPUの方が、
よりコア数4のCPUに能力的に近いと分かる結果が計測値として出るか、
という意味です

662:デフォルトの名無しさん
12/02/18 00:28:18.38
>>661
だったらあらためてNoです
HTではほとんど性能向上しません(だったような


663:デフォルトの名無しさん
12/02/18 09:15:59.39
HTって遊んでるユニットを怠けさせないで酷使させる機能に過ぎないから
遊んでるユニットが登場しないサイクルでは機能しない
なんちゃって2倍でしょ

664:デフォルトの名無しさん
12/02/18 09:36:00.16
カズ山本
 URLリンク(redstar-s.blogzine.jp)

665:デフォルトの名無しさん
12/02/18 18:34:36.09
RWHどうなった?

666:デフォルトの名無しさん
12/02/18 19:03:40.00
>>662
コア数2のノーパソから手頃かに価格のコア数2HTのノーパソに買い換えようかと思ってましたが、
Haskell 絡みではあまり幸せになれなさそうですね
コア数4くらいのがもう少し安くなるまで待つことにしました

>>663
なるほど、妙に納得しました

667:デフォルトの名無しさん
12/02/18 19:09:24.78
正確に2倍になるわけじゃないが、1.7倍ぐらいは楽勝でいくだろw

668:デフォルトの名無しさん
12/02/18 19:38:41.19
1.7倍どころかインテル自称で20%増し程度じゃないのか
その上、場合によっては遅くなったり、不具合出るオマケ付きっつー…
まぁHTとHaskellは殆ど関係ないんじゃないか?

669:デフォルトの名無しさん
12/02/18 21:01:38.89
HTで速くならないのはコンパイラがそういう最適化をしてないからだろ
1ヶ月ぐらいCPUぶん回す数値計算ならHT向けの最適化をやる意味はあるだろうが、
特に用途も決まってないHaskellが特定のCPU命令セットの最適化して意味があるとは思えないが

670:デフォルトの名無しさん
12/02/18 21:15:03.37
インテルの発表で
sandybridgeで8割に上がったような話があったような気がする。
たしか、HT:ONの場合、
マルチコア全部使い切るようなプログラムのスループットは1->0.8x2x(smp8コア/4コアの効率比が1として)=1.6ぐらい。
ただし、シングルプロセスの実行部分は、
邪魔されて0.8ぐらいまで落ちる場合があるが、
OSのプロセス管理で、なるべく占有できるところに配置される。


671:デフォルトの名無しさん
12/02/18 21:16:07.06
いままでは、7割、7.5割と上がってきてたのが8割。

672:デフォルトの名無しさん
12/02/18 21:19:56.22
コンパイラがいくらがんばっても演算密度が十分濃ければSMTで性能は上がらないでしょ

673:デフォルトの名無しさん
12/02/18 21:21:34.04
>>669
HTの効果を利用するには専用の命令セットを叩く必要があるのでしょうか

今までずっと、特に意識すること無く自動的に各HTに処理を割り振ってくれると思ってました

repa を使ってるとダイレクトにマルチコアの恩恵を受けるので、
HTで更に2倍になるならいいなぁと思ってたんですが・・・

674:デフォルトの名無しさん
12/02/18 21:25:55.33
ようするに、HTで4PC/8VCなら、
OFF:1-4が、
ON:0.7-5.6、0.75-6.0、0.8-6.4
とP4のころに比べて進化してきてるような話だったと思う。

675:デフォルトの名無しさん
12/02/18 22:14:43.49
>>673
すまん。HT用のインストラクションじゃなくて、HT用に処理をマルチスレッドに分解したり、
スレッドに適したキャッシュ配置にするような特定のCPUアーキテクチャ実行モデルを仮定した最適化という意味だった
ICCとかがそういう最適化を前面に出してるが、実際にはそれほど単純には速くならない

676:デフォルトの名無しさん
12/02/18 22:50:19.80
>>675
なるほど、でも

> HT用に処理をマルチスレッドに分解したり

この部分は、元々シングルスレッドだったものを、
コンパイラが「勝手に」上手くマルチにしてくれることは無い
という意味ですよね

もともとマルチスレッドで Haskell のソースコードを作っていたら、
実行時に勝手に HT に振り分けてくれないのですか?

そんな単純ではない?

677:デフォルトの名無しさん
12/02/18 23:00:34.29
文字列で日本語使えないのでしょうか?

678:675
12/02/18 23:03:27.58
>>676
近所でICCでMPIをやってる人がいたが、期待したほど速くならなくて困ってた
なので、Haskellもそんなにうまく速くなるわけではないと思ってるけど、
速くなるのなら型システムよりもすごいことなんじゃないかと思う

679:デフォルトの名無しさん
12/02/18 23:11:59.78
>>677
もう少し問題をハッキリさせようか

今の Haskell は標準で UTF-8 でエンコードされた文字データを処理できる
ここでいう処理というのは、Char 型の変数にデータを束縛できるという意味

>>677 は何が問題だと感じている?

あと環境も教えてくれ(OS やコンパイラのバージョンなど)

680:デフォルトの名無しさん
12/02/18 23:19:22.20
>>678
例えば、Haskell で repa を使って画像データを配列に読み込んで、
それに対してぼかし処理とか FFT 処理とか施したりする場合、
2コアCPUを使って RTS オプション -N1 と -N2 とでは全く処理速度が違う
驚くと同時に感動すら覚える

HTを持つCPUも、コアが増えたのと同程度とは期待していないが、
1.5倍程度は速くならないかなと思ってたんだけど

だれか試してくれないかな

681:デフォルトの名無しさん
12/02/18 23:25:09.94
>>679
CSVファイル(Excelで出力したShift_JIS)を読み込んで、lines関数で分割した後、id関数に入れて、そのままunlinesしてファイルに出力したら日本語の場所が文字化けしてるです
Haskellそのものの仕様で使えないのか、入力系かParsecか出力系のエラーで使えないのか、特殊な文字列データ型を入れれば使えるのか知りたいです
Windows7、The Glorious Glasgow Haskell Compilation System, version 6.12.3 です

もしHaskellそのものの仕様で日本語が使えないのならCSVファイルを編集して日本語部分を全部ASCIIコードでローマ字にします

682:デフォルトの名無しさん
12/02/18 23:44:47.47
>>681
下記のコードで全く問題なく Shift_JIS をロードして Shift_JIS で保存された

writeFile "test2.txt" =<< return . unlines . id . lines =<< readFile "test.txt"

[環境]
Windows7
GHC 7.4.1

683:デフォルトの名無しさん
12/02/18 23:49:00.05
>>680
repaすごいな
ここまでマルチコア意識してるなら速くなりそうな気がするな

684:682
12/02/19 00:40:54.82
>>681
ちなみに、>>682 のコードの id の部分を map (take 3) とかにした場合、
保存されたテキストを Shift_JIS として解釈する(開く)と文字化けして見える

何も加工しなければ、読み込んだデータの形のまま保存される
(例えば SQL で Shift_JIS の文字列を読み込んでそのまま出力する場合も含む)

文字単位で加工したければ、
読み込み前に CSV ファイルを予め UTF-8 に変換しておくか、
あるいは読み込んだ後に UTF-8 に変換する必要がある
(例えば iconv パッケージを使う)

そして、例えば Data.String.UTF8(utf8-stringパッケージ)を使って加工するとか

685:デフォルトの名無しさん
12/02/19 01:50:54.96
>>684
ParsecでCSVファイルの解析をためしたら文字化けしてたから、idとかに変えていろいろ試してました
これ結局、Parsecを間に入れてファイル入出力する場合は文字コードの変換を明示しないとダメということなんですね


686:682
12/02/19 02:13:53.28
>>685
そう
Parsec で日本語を処理したいのなら、処理前に UTF-8 にエンコードしないとダメ

参考になりそうなページ
URLリンク(snak.tdiary.net)

687:デフォルトの名無しさん
12/02/19 09:55:24.28
あれ、Hackage落ちてる?

688:デフォルトの名無しさん
12/02/19 15:43:45.81
諸君、お薦めのライブラリは何かね?

689:デフォルトの名無しさん
12/02/19 15:51:43.82
prelude

690:デフォルトの名無しさん
12/02/19 15:58:31.27
Data.List もなかなか

691:デフォルトの名無しさん
12/02/19 15:58:44.91
こやつめ!ハハッ!

692:デフォルトの名無しさん
12/02/19 16:00:51.90
僕はForeignちゃん!

693:デフォルトの名無しさん
12/02/19 21:52:36.96
すみません、質問させてください。以下のコードが、なぜか意図した通りに動作しません。
(一応なるべく簡略化したので、このコード自体に深い意味はないです)

combination n r =div (product [1..n]) (product [1..r] * product [1..n-r])
f n = length (takeWhile (<=4000) (map (combination n) [1..5] ))
hoge = [n - f n | n<-[20]]

私はこの hoge を [20 - f 20] のつもりで書きました。GHCで [20 - f 20] と入力すると 17 と返ってくるので、 hoge は [17] になっていてほしいです。
なのに、なぜか hoge と入力すると [15] が返ってきます。どなたかどこが誤っているのかわかる方がいらっしゃったら教えていただけないでしょうか。

694:デフォルトの名無しさん
12/02/19 22:36:50.85
>>693
product [1..20]がオーバーフローしている。

ghciで [20 - f 20] としたときはたぶんf 20の20がIntegerとして評価されているからオーバーフローが生じていない。
ghciで[20 - f (20 :: Integer)]と[20 - f (20::Int)]を比較して、考えれば、言っていることが分かるだろう。

695:デフォルトの名無しさん
12/02/19 22:39:24.02
>>693
原因は >>694 の通り

解決方法の一つは、f 関数内で length 関数の代わりに genericLength 関数を使う

696:694
12/02/19 22:43:26.21
import Data.ListしてlengthのかわりにgenericLengthを使えば解決するみたい

697:695
12/02/19 22:43:45.05
すまん、
その >>693 の(型シグネチャを省いた)例なら、
genericLength 関数を使えば自動的に全て解決するという意味

実際のコードで型シグネチャを書いてる場合、
例えば combination 関数の型が Int -> Int なら、
それも Integer に直す必要がある

698:694
12/02/19 22:44:07.36
だから、リロードしろとorz

699:デフォルトの名無しさん
12/02/19 22:54:59.05
やっぱりIntは撲滅すべきだわ

700:デフォルトの名無しさん
12/02/19 22:58:28.08
単一の式では、nとnは同じ型でないといけないけど、
20と20が同じ型である必要はないってことだね
「lengthがIntegral a => a型ではなくInt型を返すのはまったく馬鹿げたこと」
だっけか


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch