トップページtech
990コメント380KB

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん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/
0653デフォルトの名無しさん2012/02/17(金) 21:35:16.99
急いで読まない
0654デフォルトの名無しさん2012/02/17(金) 21:59:05.59
コードを写経して動かなくても文句言わない
0655デフォルトの名無しさん2012/02/17(金) 22:12:05.67
なんか、ものすんごい勢いでレスついてるね。
みんな暇か?
0656デフォルトの名無しさん2012/02/17(金) 22:15:37.70
詰まったり解らなかったり動かなかったら本家(>>5の上)のコメントなんかも参照
一日で読み切れなくても泣かない投げない
0657デフォルトの名無しさん2012/02/17(金) 22:19:09.47
>>652
最初からまじめに読んでいくと冗長度が高くて飽きる。飛ばして途中から見ると何言ってるのか分からない。
昆虫本には良くあることです
0658デフォルトの名無しさん2012/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つのスレッドが平行して動くのでしょうか
0659デフォルトの名無しさん2012/02/17(金) 22:30:08.58
RWH一日は無理だろ
0660デフォルトの名無しさん2012/02/17(金) 23:04:02.43
>>658
>GHC のマルチコア機能はHTに対応するのでしょうか => Yes
>ちゃんと4つのスレッドが平行して動くのでしょうか => No
ちゃんとの意味にもよると思いますが
詳しくはwikipediaを
0661デフォルトの名無しさん2012/02/17(金) 23:25:23.88
>>660
> ちゃんとの意味にもよると思いますが

例えば RTSオプションで -s を指定して実行して得られる情報において、
コア数2のCPUよりコア数2HTのCPUの方が、
よりコア数4のCPUに能力的に近いと分かる結果が計測値として出るか、
という意味です
0662デフォルトの名無しさん2012/02/18(土) 00:28:18.38
>>661
だったらあらためてNoです
HTではほとんど性能向上しません(だったような
0663デフォルトの名無しさん2012/02/18(土) 09:15:59.39
HTって遊んでるユニットを怠けさせないで酷使させる機能に過ぎないから
遊んでるユニットが登場しないサイクルでは機能しない
なんちゃって2倍でしょ
0664デフォルトの名無しさん2012/02/18(土) 09:36:00.16
カズ山本
 ttp://redstar-s.blogzine.jp/redstar/images/softbank_hawks_store-img444x600-1121339119kazu_yamamoto.jpg
0665デフォルトの名無しさん2012/02/18(土) 18:34:36.09
RWHどうなった?
0666デフォルトの名無しさん2012/02/18(土) 19:03:40.00
>>662
コア数2のノーパソから手頃かに価格のコア数2HTのノーパソに買い換えようかと思ってましたが、
Haskell 絡みではあまり幸せになれなさそうですね
コア数4くらいのがもう少し安くなるまで待つことにしました

>>663
なるほど、妙に納得しました
0667デフォルトの名無しさん2012/02/18(土) 19:09:24.78
正確に2倍になるわけじゃないが、1.7倍ぐらいは楽勝でいくだろw
0668デフォルトの名無しさん2012/02/18(土) 19:38:41.19
1.7倍どころかインテル自称で20%増し程度じゃないのか
その上、場合によっては遅くなったり、不具合出るオマケ付きっつー…
まぁHTとHaskellは殆ど関係ないんじゃないか?
0669デフォルトの名無しさん2012/02/18(土) 21:01:38.89
HTで速くならないのはコンパイラがそういう最適化をしてないからだろ
1ヶ月ぐらいCPUぶん回す数値計算ならHT向けの最適化をやる意味はあるだろうが、
特に用途も決まってないHaskellが特定のCPU命令セットの最適化して意味があるとは思えないが
0670デフォルトの名無しさん2012/02/18(土) 21:15:03.37
インテルの発表で
sandybridgeで8割に上がったような話があったような気がする。
たしか、HT:ONの場合、
マルチコア全部使い切るようなプログラムのスループットは1->0.8x2x(smp8コア/4コアの効率比が1として)=1.6ぐらい。
ただし、シングルプロセスの実行部分は、
邪魔されて0.8ぐらいまで落ちる場合があるが、
OSのプロセス管理で、なるべく占有できるところに配置される。
0671デフォルトの名無しさん2012/02/18(土) 21:16:07.06
いままでは、7割、7.5割と上がってきてたのが8割。
0672デフォルトの名無しさん2012/02/18(土) 21:19:56.22
コンパイラがいくらがんばっても演算密度が十分濃ければSMTで性能は上がらないでしょ
0673デフォルトの名無しさん2012/02/18(土) 21:21:34.04
>>669
HTの効果を利用するには専用の命令セットを叩く必要があるのでしょうか

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

repa を使ってるとダイレクトにマルチコアの恩恵を受けるので、
HTで更に2倍になるならいいなぁと思ってたんですが・・・
0674デフォルトの名無しさん2012/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のころに比べて進化してきてるような話だったと思う。
0675デフォルトの名無しさん2012/02/18(土) 22:14:43.49
>>673
すまん。HT用のインストラクションじゃなくて、HT用に処理をマルチスレッドに分解したり、
スレッドに適したキャッシュ配置にするような特定のCPUアーキテクチャ実行モデルを仮定した最適化という意味だった
ICCとかがそういう最適化を前面に出してるが、実際にはそれほど単純には速くならない
0676デフォルトの名無しさん2012/02/18(土) 22:50:19.80
>>675
なるほど、でも

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

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

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

そんな単純ではない?
0677デフォルトの名無しさん2012/02/18(土) 23:00:34.29
文字列で日本語使えないのでしょうか?
06786752012/02/18(土) 23:03:27.58
>>676
近所でICCでMPIをやってる人がいたが、期待したほど速くならなくて困ってた
なので、Haskellもそんなにうまく速くなるわけではないと思ってるけど、
速くなるのなら型システムよりもすごいことなんじゃないかと思う
0679デフォルトの名無しさん2012/02/18(土) 23:11:59.78
>>677
もう少し問題をハッキリさせようか

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

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

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

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

だれか試してくれないかな
0681デフォルトの名無しさん2012/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コードでローマ字にします
0682デフォルトの名無しさん2012/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
0683デフォルトの名無しさん2012/02/18(土) 23:49:00.05
>>680
repaすごいな
ここまでマルチコア意識してるなら速くなりそうな気がするな
06846822012/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パッケージ)を使って加工するとか
0685デフォルトの名無しさん2012/02/19(日) 01:50:54.96
>>684
ParsecでCSVファイルの解析をためしたら文字化けしてたから、idとかに変えていろいろ試してました
これ結局、Parsecを間に入れてファイル入出力する場合は文字コードの変換を明示しないとダメということなんですね
06866822012/02/19(日) 02:13:53.28
>>685
そう
Parsec で日本語を処理したいのなら、処理前に UTF-8 にエンコードしないとダメ

参考になりそうなページ
http://snak.tdiary.net/20110104.html
0687デフォルトの名無しさん2012/02/19(日) 09:55:24.28
あれ、Hackage落ちてる?
0688デフォルトの名無しさん2012/02/19(日) 15:43:45.81
諸君、お薦めのライブラリは何かね?
0689デフォルトの名無しさん2012/02/19(日) 15:51:43.82
prelude
0690デフォルトの名無しさん2012/02/19(日) 15:58:31.27
Data.List もなかなか
0691デフォルトの名無しさん2012/02/19(日) 15:58:44.91
こやつめ!ハハッ!
0692デフォルトの名無しさん2012/02/19(日) 16:00:51.90
僕はForeignちゃん!
0693デフォルトの名無しさん2012/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] が返ってきます。どなたかどこが誤っているのかわかる方がいらっしゃったら教えていただけないでしょうか。
0694デフォルトの名無しさん2012/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)]を比較して、考えれば、言っていることが分かるだろう。
0695デフォルトの名無しさん2012/02/19(日) 22:39:24.02
>>693
原因は >>694 の通り

解決方法の一つは、f 関数内で length 関数の代わりに genericLength 関数を使う
06966942012/02/19(日) 22:43:26.21
import Data.ListしてlengthのかわりにgenericLengthを使えば解決するみたい
06976952012/02/19(日) 22:43:45.05
すまん、
その >>693 の(型シグネチャを省いた)例なら、
genericLength 関数を使えば自動的に全て解決するという意味

実際のコードで型シグネチャを書いてる場合、
例えば combination 関数の型が Int -> Int なら、
それも Integer に直す必要がある
06986942012/02/19(日) 22:44:07.36
だから、リロードしろとorz
0699デフォルトの名無しさん2012/02/19(日) 22:54:59.05
やっぱりIntは撲滅すべきだわ
0700デフォルトの名無しさん2012/02/19(日) 22:58:28.08
単一の式では、nとnは同じ型でないといけないけど、
20と20が同じ型である必要はないってことだね
「lengthがIntegral a => a型ではなくInt型を返すのはまったく馬鹿げたこと」
だっけか
0701デフォルトの名無しさん2012/02/19(日) 23:21:56.89
>>699
それは無い

ただ、オーバーフローしたのならしたと分かるような、
デバッグ用の RTS オプションとかあるといいな
07026932012/02/19(日) 23:52:01.42
>>694-697,700
なるほど、そういうことでしたか。型宣言は省略していたので、おっしゃる通り genericLength という関数を(初めて見ました)使うことで解決しました。
質問前にコードを書き換えて実験していたとき、 hoge = [f n | n<-[20]] とするとちゃんと [f 20] に一致するのが不思議だったのですが、それも >>700 を読んで合点がいきました。
単に f n と書くと Integer 型として扱われるが、n - f n と書いた場合には n が Int 型になってしまっていたのですね。それでオーバーフローしたと。
自分では絶対に気づきませんでした…。お三方(お二方?)ご親切にありがとうございます。
0703デフォルトの名無しさん2012/02/20(月) 12:44:31.59
windowsでgtk2hsの最新版に-threadedつけたら普通にぶっ壊れてワロタ
その問題は直ったって言ったじゃないですかー!
0704デフォルトの名無しさん2012/02/22(水) 01:04:11.99
wondowにこだわってたら、面倒は多いだろうからな。
0705デフォルトの名無しさん2012/02/22(水) 18:49:36.88
>>703
Haskellに限らず、gtk全般がwindowsと相性が悪いと思うのは私だけでしょうか?
0706デフォルトの名無しさん2012/02/22(水) 19:12:47.80
wxWisgets の方が安定してるような感じはするな

今は wxpack もあって、Haskell で使うのも、
特別なことをしなければ gtk2hs 並に簡単になった
0707デフォルトの名無しさん2012/02/22(水) 19:21:08.18
GUIはVBやVCでインターフェイス作って、パイプ通してHaskell使ってる
0708デフォルトの名無しさん2012/02/22(水) 19:31:59.91
wxHaskellっててっきり開発止まってるんだと思ってたら
一月に新しいの出てんのね
ちょっと移るか・・・
0709デフォルトの名無しさん2012/02/23(木) 21:38:20.07
permutationパッケージって不便じゃない?
重複もある要素群から組合せや順列作りたい時どうするの?
0710デフォルトの名無しさん2012/02/24(金) 00:08:55.34
Haskellの名前空間ってどうなってんの?
二つの別のモジュールで同名の関数定義してたらmoduleName.は略せない
0711はちみつ餃子 ◆8X2XSCHEME 2012/02/24(金) 00:48:25.04
候補が複数ある関数を使ったときだけエラーにすればいいと思うんだよな。
実際に使ってない関数で衝突があってもどうでもいいじゃん。
0712デフォルトの名無しさん2012/02/24(金) 03:21:55.39
>>710-711
それぞれのモジュールをインポートするときに
インポートする関数名を明示的に指定するんじゃだめなのかね?
0713デフォルトの名無しさん2012/02/24(金) 07:30:30.90
>>710
指摘している問題箇所がよく分からない
こちらの環境(GHC 7.4.1)で試したら、全く問題なかったんだが

-----[ Mod1.hs ]-----
module Mod1 (t1, t2) where
t1 = (*3)
t2 = (+7)

-----[ Mod2.hs ]-----
module Mod2 (t1, t3) where
t1 = (*5)
t3 = (+13)

-----[ ModC.hs ]-----
module ModC where
import Mod1
import Mod2
f = t2
g = t3

ghci でエラーも無く ModC をロードできる
当然、関数 f や g は普通に使える
また、ghc で実行ファイルやライブラリにコンパイルする事もできる

ModC で関数 t1 を使おうとすると Ambiguous occurrence エラーが出る
その場合はモジュールを明示するか、import でエイリアス名を指定すれば良い

何が問題なんだ?
0714デフォルトの名無しさん2012/02/25(土) 17:50:44.36
Cabal の挙動がいまいちよく分かりません

*.cabal ファイルに例えば以下のような記述があった場合

flag ichigo
  default: False

if flag(ichigo)
  ---[ A ]---
else
  ---[ B ]---

configure に [A] が通るのか [B] が通るのか、どちらなのでしょうか
0715デフォルトの名無しさん2012/02/26(日) 18:39:03.77
forallってオプションと共に用いて
型の決め打ちを段階的に遅延してもらうものだと思えばいいの?
0716デフォルトの名無しさん2012/02/27(月) 07:24:50.28
>>715
どうしてそう思う?

(違うと言ってるんじゃなくて、単純にその考え方に興味があるだけです)
0717デフォルトの名無しさん2012/02/27(月) 08:03:50.64
id:: a -> a

(\f -> (f 1,f "1")) id

No instance for (Num [Char])
arising from the literal `1' at <interactive>
Possible fix: add an instance declaration for (Num [Char])
In the first argument of `f', namely `1'
In the expression: f 1
In the expression: (f 1, f "1")

これがエラーになるのは
コンパイル時に最初に評価したほうの型で固定しちゃうからでしょう?

最初に解釈した段階でid 1だから
id::Int -> Int
で固定しちゃう

次にid "1" をみてなんだこりゃ?
id:: String -> Stringなんて聞いたこと無いぞ!とコンパイラが怒り出す

この悲劇を回避するために
決め打ちは一段階待ってくれ
a -> a のまま進んでくれ
ってのがforallとXRank2Typesオプションのセットの役目なんじゃないの?

評価の遅延じゃん?
実行の遅延評価じゃなくてコンパイル時の型の遅延評価だから
メタ遅延評価的な
0718デフォルトの名無しさん2012/02/27(月) 12:45:29.31
評価順序によらないはずなのに「最初に評価したほうの型」ってなるのが面白いね。
値を遅延評価できても、型も遅延評価できるとは限らないんだな。
0719デフォルトの名無しさん2012/02/27(月) 13:20:52.44
あくまでコンパイル時の話だし
静的に型付けて片付ける型の言語だし
そのくらい大目に見てやれよ
0720 [―{}@{}@{}-] デフォルトの名無しさん2012/02/27(月) 17:39:59.79
決め打ちするのはその通りだけど順番は関係ないよ
どっちから型を付けても(エラーメッセージ以外は)同じ結果になる
0721デフォルトの名無しさん2012/02/27(月) 21:39:35.38
forall の話が出たんで、理解をより深めようと調べてたんだけど、
http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types
このページで分からない部分がある

[Explaining the term existential] のセンテンスの
「But we got almost the same behaviour above using datatypes. Let's declare one.」
の直前まではなんとか分かった

forall = 積集合
exists = 和集合(Haskell の構文には無い)

というのも、納得はできないが、とりあえずそういうものだと見なす事にする
で、そのすぐ下の「MkT :: forall a. a -> T」 の意味を説明している部分がよく分からない

これまでの話の流れからすると、forall a. (a -> T) というのが、
どういう型(を意味する集合)の積集合になるかを考えれば良いんだよな

つまり、

Int -> T という型を意味する集合が持つ要素
String -> T という型を意味する集合が持つ要素
・・・

などに共通する要素だけを持つ型が forall a. a -> T なんだよな
ここまでは合ってる?

で、その共通する要素って、ボトム以外に具体的にどういうものがあるのかな
と考えてみると・・・ よく分からない

「何かを入力して型 T の値を得る関数」というのがそれかなと初め思ったけど、
じゃあこれは例えば「Int -> T という型を意味する集合が持つ要素」に含まれているのか
と考えると、なんか違う気がする
0722デフォルトの名無しさん2012/02/27(月) 23:11:20.23
エラー
(\f -> (f 1, f "1")) id

積集合
(\(f,f') -> (f 1, f' "1")) (id,id)

和集合
id' (Left x) = Left (id x)
id' (Right x) = Right (id x)
(\f -> (f (Left 1), f (Right "1"))) id'

集合が有限なら、forallとexistsは不要です。
0723デフォルトの名無しさん2012/02/27(月) 23:52:14.92
時間の無駄
0724デフォルトの名無しさん2012/02/28(火) 00:04:14.04
無限リストを扱えるから限定子が必要 という説明からはじめてくれないと困る
0725デフォルトの名無しさん2012/02/28(火) 03:02:25.61
>>721
俺は共通する要素とか集合って考えるより、
特定の型に依存しない性質を含んだ関数って考えた方がピンとくるな。

>で、その共通する要素って、ボトム以外に具体的にどういうものがあるのかな
要するにT aという型のコンテナTに対して、格納しているa型の値に直接触れずに、
コンテナの構造だけを変えたり(flatten :: forall a. Tree a -> [a]、tail :: forall a. [a] -> [a]とか)、
コンテナ自体の情報を返す(length :: forall a. [a] -> Int)類の関数。
特にリストのhead、(!)とか、タプルならfst、sndみたいに値を取り出すような関数も、
中身に触れなければ型に依存しない性質は保たれるってのは重要。
0726デフォルトの名無しさん2012/02/28(火) 07:44:27.79
>>722
それは俺(>>721)に対する返信?

もしそうなら、>>721 のページで言ってる forall = 積集合 という場合の集合は、
{⊥, 0, -1, 1, -2, 2, ...} を要素に持つInt型という名前の集合
{⊥, True, False } を要素に持つBool型という名前の集合
{⊥, "kyu-ri", "daikon", ...} を要素に持つString型という名前の集合
・・・
という意味の集合だと思うんだけど

で、例えば forall a. a は「全ての型(集合)の積集合」だから、
{⊥} を要素に持つ集合、つまり⊥しか値を取り得ない型になる

これと >>722 との繋がりがよく分からない(繋がった話ならという場合だけど)


>>725
同じだ、俺も今まで似たような考え方でやってきたんだ

それはそれとして、では >>721 のページに載っている考え方だと、
MkT :: forall a. a -> T はどう説明できるのかなという話
0727デフォルトの名無しさん2012/02/28(火) 10:03:32.17
>>726
Int型はIntの値の集合ではなく、Intの値を取り出せるデータ構造の集合だ、と定義すればいい。
例えば、0というデータから取り出せるのはIntだけでなく、Doubleも取り出せる。
forall a. a->TからはInt->TやDouble->Tなどを取り出せる。
0728デフォルトの名無しさん2012/02/28(火) 12:47:20.41
>>727
いや、ちょっと待って
そうやって勝手に話の前提を変えた場合、>>721 のリンク先の話は
ちゃんと整合性を保って説明できるのだろうか
(整合性を保って説明できるように隠れた定義を暴き出してくれたのなら大変有り難いが)

リンク先ではハッキリと

Bool is the set {True, False, ⊥},
Integer is the set of integers (and bottom),
String is the set of all possible strings (and bottom),
and so on.

と定義されていて、これを前提にしてその後の話が続いている


> forall a. a->TからはInt->TやDouble->Tなどを取り出せる。

もしそうだとすると、forall a. a からは Int も Double も取り出せるということ?
0729デフォルトの名無しさん2012/02/28(火) 13:07:28.91
⊥しか取りえないってのは間違い。
MkT :: forall a. a -> Tはどんな値でも取ってT型を返す関数。
全称量化することで、型パラメータaが取り得る全ての型に共通の性質だけにしか言及できなくなる。
で、結局の所、⊥か、それ以外の何かが入ってる、としか言えなくなる。
(もちろんisBottomみたいな関数は定義できないから、実質何が入ってるかは不明)
forallが積集合云々ってのは、このことを言いたいんじゃないかと思う、多分。

一応、
foo (MkT x) = x :: T -> a
bar (MkT x) = id x :: T -> a
dup (MkT x) = (x, x) :: T -> (a, a)
みたいな関数は定義できる。
まぁT型の定義じゃ意味のある関数は定義できないけれど、値を取り出して関数適用するだけならおkだから、
型制約付けといたり、関数とセットで入れとくと、OOPっぽいポリモーフィズムできるようになったりする。
ttp://www.kotha.net/ghcguide_ja/latest/data-type-extensions.html#existential-quantification

(件のページのNotesみて初めて知ったけど、WHNFに簡約はできるって発想は無かった…)
0730デフォルトの名無しさん2012/02/28(火) 13:59:49.98
初心者で申し訳ありません。
ggrksとか言わないで下さい。ググッた結果↓
⊥ に一致する情報は見つかりませんでした。
0731デフォルトの名無しさん2012/02/28(火) 20:16:28.02
>>730
⊥ はボトムと読みます
0732デフォルトの名無しさん2012/02/28(火) 21:17:38.37
* LLクズがウォーミングアップを始めたようです! *
0733デフォルトの名無しさん2012/02/28(火) 23:59:59.80
学部時代にHaskellに没頭していた俺ですが、今では立派なPython厨です
0734デフォルトの名無しさん2012/02/29(水) 02:29:52.31
Web+DB誌に山本和彦によるHaskell入門が載ってるみたいだけど、読む価値ありますか?
0735デフォルトの名無しさん2012/02/29(水) 03:25:58.19
雑誌の言語紹介記事なんてのは布教用だから、
Haskellerが読むようなものじゃない。
0736デフォルトの名無しさん2012/02/29(水) 06:23:56.45
その記事で、Learn You a Haskell for Great Good!の訳本出るって書いてる
『すごいHaskell たのしく学ぼう!』
* 田中英行、村主崇行訳
* オーム社
* 2012年5月発売予定

まあいいんだけど、タイトルダサいな。
0737デフォルトの名無しさん2012/02/29(水) 07:53:36.61
>>729
> 全称量化することで、型パラメータaが取り得る全ての型に共通の性質だけにしか言及できなくなる。

>>726 でも言ったが、俺も普段は似たような考え方で forall を扱っている
しかし、この考え方とリンク先のページで述べられている考え方との整合性がなんか上手く取れないんだ
(たぶん同じ forall について我々とリンク先は別の視点、捉え方で見ていると思うんだ)

> ⊥しか取りえないってのは間違い。

例えば >>726 を繰り返すが
(読み返してみて、誤解を与える表現に気づいたので括弧は外した)

⊥, 0, -1, 1, -2, 2, ... を要素に持つInt型という名前の集合
⊥, True, False を要素に持つBool型という名前の集合
⊥, "kyu-ri", "daikon", ... を要素に持つString型という名前の集合

ゆえに forall a. a は ⊥ を要素に持つ(名前は知らん)集合

という考え方を取っている(これはハッキリ書かれている、と俺は思う)

貴方や俺が普段取っている「型パラメータaが取り得る全ての型に共通の性質」という考え方ならば、
例えば forall a. (Show a) => a とすれば、その共通する性質をさらに (Show a) と絞り込む
という風に素直に考えられ、実際のコンパイラの挙動とも合致する

しかし、リンク先の考え方だと、forall a. a で {⊥} という集合なら、
これに対して (Show a) という性質で絞り込むことがちょっと想像できない
forall a. a -> T についても同じ

リンク先の言いたいことは何なんだろうというのが疑問なんだが、
申し訳ない >>729 でもまだ疑問が解消されない
(やっぱりそう考えた方が今はまだ分かりやすいな、という気持ちは再確認できたが)
0738デフォルトの名無しさん2012/02/29(水) 16:00:11.89
729は「aの性質に言及するのをやめれば、共通の要素を作れる」と言っている
737は「aの性質を考えると、共通の要素は⊥しかない」と言っている

つまり、型を考えるのをやめれば便利なものを作れるが、
型を考えると、そんな便利なものは存在しないということを証明できる
0739デフォルトの名無しさん2012/02/29(水) 19:01:47.59
>>738
ごめん、どういうことなのか、ちょっと分からない
混乱してる

>>737(俺)が言ってるんじゃなくて、言ってるのは俺が示したリンク先のページだよ
そして、aの性質を考えるとじゃなくて、forall の性質=積集合を考えると、ね
a は単に forall に束縛された型変数で、重要な性質を持ってるのは forall の方だと俺は思う


よく分からないけど、俺の疑問の解消に少しでも繋がるような
何か証明ができるのなら、是非してみてほしい
お願いする
0740デフォルトの名無しさん2012/02/29(水) 20:01:40.01
>>739
じゃあMkTという関数があってMkTの型(a->T)は(aに関しては)重要ではないとする
重要ではないので適当に
MkT ∈ (Int->T)
MkT ∈ (Bool->T)
MkT ∈ (String->T)
・・・
ということにすればMkT ∈ (forall a. (a->T))
だから(forall a. (a->T))には⊥以外の要素が入っている
0741デフォルトの名無しさん2012/02/29(水) 20:17:30.41
>>740
確認したいんだが、

MkT ∈ (Int->T)
MkT ∈ (Bool->T)
MkT ∈ (String->T)
・・・

これは全て AND で結ばれているんだよな
つまり、全ての積集合を意味しているんだよな

{MkT ∈ (Int->T)} AND {MkT ∈ (Bool->T)} AND {MkT ∈ (String->T)} ...
0742デフォルトの名無しさん2012/02/29(水) 20:46:56.98
>>741
そうだね
ANDだね
0743デフォルトの名無しさん2012/02/29(水) 20:58:30.82
積じゃなくて直積じゃね?
0744デフォルトの名無しさん2012/02/29(水) 21:00:47.10
>>743
どうして?
0745デフォルトの名無しさん2012/02/29(水) 21:21:11.49
ごめん勘違い、そこは積集合であってる
0746デフォルトの名無しさん2012/03/01(木) 02:57:49.52
(Int -> T)は
{ ⊥, (\x -> T), (\x -> let _ = x + 1 in T), ... }

(String -> T)は
{ ⊥, (\x -> T), (\x -> let _ = x ++ "foo" in T), ... }

forall a. (a -> T)は
{ ⊥, (\x -> T) }
0747デフォルトの名無しさん2012/03/01(木) 03:05:14.44
ちょっと間違い
forall a. (a -> T)は
{ ⊥, (\x -> T), (\x -> let _ = x in T), ... }
だった
つまり書く集合の内xをIntなどの具体的な型として
扱っていない項だけが残る
0748デフォルトの名無しさん2012/03/01(木) 07:23:19.60
>>746, >>747
すげー分かりやすかった

なるほど、forall a. a の時のように、
ちゃんとそれぞれの型の場合の取り得る値の集合の積で考えられるんだ
合点がいった

ありがと
スッキリしたから、もう少し先まで読み進めてみる
0749デフォルトの名無しさん2012/03/01(木) 12:01:47.26
【言語別成果物】
PHP「掲示板作りました!」
Ruby「Railsで住所管理アプリ作りました!」
Java「帳票管理ソフト作りました!」
ActionScript「ゲーム作りました!」
Lisp「Lisp作りました!」
Haskell「美しい言語だ…(成果物無し」

Haskellやる理由ってエンジニアとしてのステータスなんだよね
昔の言語LISPに触れるとか、古参気取ったり
インテリンゲンジャを気取るためにHaskellやってますとかね
馬鹿じゃねーの?wwwwwwwwwwwww
死ねよいいから
お前ら目さませよクズ!?!!?
本当に!!

おまえらさ!? 
Haskellやってて
名に作ったの?

クズHaskell使い「作ったとかじゃなくて・・・そもそも何故作るのか」

スキルアップ(笑)で終わってると思うよお前ら

Matzの布教活動に釣られたクズ当然だなwwwwwwwwwwwwwwwwwwwwwwwwwwww
0750デフォルトの名無しさん2012/03/01(木) 12:07:21.59
> インテリンゲンジャ
これは新しい
0751デフォルトの名無しさん2012/03/01(木) 12:09:43.91
難しいがかっこいい
マイナーがかっこいい

とか美徳感じてるクズばっかりだからな
0752デフォルトの名無しさん2012/03/01(木) 12:22:52.87
また、pearl忍者が復活したのか。偏狭な視点と幼稚臭い書き込みですぐ分かる。
■ このスレッドは過去ログ倉庫に格納されています