1 名前:デフォルトの名無しさん mailto:sage [2007/10/30(火) 20:28:13 ] haskell.org www.haskell.org/ 日本語サイト www.sampou.org/cgi-bin/haskell.cgi www.shido.info/hs/ 過去ログ 関数型プログラミング言語Haskell Part1 pc.2ch.net/tech/kako/996/996131288.html Part2 pc2.2ch.net/test/read.cgi/tech/1013846140/ Part3 pc8.2ch.net/test/read.cgi/tech/1076418993/ Part4 pc8.2ch.net/test/read.cgi/tech/1140717775/ Part5 pc8.2ch.net/test/read.cgi/tech/1149263630/ Part6 pc11.2ch.net/test/read.cgi/tech/1162902266/ Part7 pc11.2ch.net/test/read.cgi/tech/1174211797/ ・2chの仕様により、行頭の半角スペースは表示されません。 コードをインデントしたいときは、代わりに または全角スペースを使うことができます。
175 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 07:11:03 ] >>174 型推論。fooの型とbarの型とその式の使われ方が勘案される。
176 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 11:11:46 ] >>175 それはコンパイル時と実行時のどちらでされるものなんでしょうか?
177 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 11:43:58 ] >>176 実行時
178 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 11:57:24 ] ・型推論自体はコンパイル時。 ・ただし、型クラスのディスパッチは実行時まで遅延される。 ・ただし、どのインスタンスについてのコードを生成すれば良いか静的に決まる場合は、 最適化の一環としてディスパッチを省略する。 こんな感じか。
179 名前:174 mailto:sage [2007/11/17(土) 12:49:35 ] >>177 、178 なるほど、静的に型をチェックしつつ、動作は動的に決まるんですね。 ところで 数学パズル ものまね鳥をまねる―愉快なパズルと結合子論理の夢の鳥物語 ttp://www.amazon.co.jp/%E6%95%B0%E5%AD%A6%E3%83%91%E3%82%BA%E3%83%AB-%E3%82%82%E3%81%AE%E3%81%BE%E3%81%AD%E9%B3%A5% E3%82%92%E3%81%BE%E3%81%AD%E3%82%8B%E2%80%95%E6%84%89%E5%BF%AB%E3%81%AA%E3%83%91%E3%82%BA%E3%83%AB%E3%81%A8%E7%B5% 90%E5%90%88%E5%AD%90%E8%AB%96%E7%90%86%E3%81%AE%E5%A4%A2%E3%81%AE%E9%B3%A5%E7%89%A9%E8%AA%9E-%E3%83%AC%E3%82%A4%E3% 83%A2%E3%83%B3%E3%83%89-%E3%82%B9%E3%83%9E%E3%83%AA%E3%83%A4%E3%83%B3/dp/4627019017/ref=sr_1_9?ie=UTF8&s=books&qid=1195271100&sr=1-9 この本を読んだことがある人いますか?関数プログラミングの土台の考え方がわかる本らしいんですが。
180 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 13:28:59 ] >>179 途中まで読んだだけだけどコンビネータの話。 S,K,I とか。Yコンビネータも出てきたかは覚えてない。
181 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 16:07:56 ] a 1 = "hoge" a 2 = 2 のような引数によって異なる型の値を返すことはOKなんでしょうか?
182 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 16:22:37 ] >>181 template haskell
183 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 16:25:26 ] >>181 ダメ
184 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 16:30:24 ] 2種類の型のどちらかを返したい場合はEitherを使う。 a :: Int -> Either String Int a 1 = Left "hoge" a 2 = Right 2
185 名前:182 mailto:sage [2007/11/17(土) 16:51:52 ] template haskellじゃなくてgeneric haskellだった・・
186 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 22:16:41 ] >>163 今日Haskell始めたばかりのド素人なんだけど、 ones = addlist 1 onesでも、 addlist init xs = init : head xs : tail xs -- [1,1,1,1,1,1,1,1,1,1] addlist init xs = init : xs -- [1,1,1,1,1,1,1,1,1,1] addlist init ~(x:xs) = init : x : xs -- [1,1,1,1,1,1,1,1,1,1] addlist init (x:xs) = init : x : xs -- C stack overflow ってなる。要するに(x:xs)が含まれる部分が先に解釈されるとマズいってことじゃないかな。 単体でのxsはパターンはパターンでも手続き型言語での仮引数と同じ程度の意味しかもたないパターンだから暗黙的に遅延される。 head xsやtail xsも関数だからxsが未確定なら遅延される。 でも(x:xs)というパターンは未確定でも遅延しないでxとxsを照合しようとする。 結果的にinitに値がセットされる前にx:xsを延々と調べ続ける。それではマズいので、(x:xs)を遅延パターンにする、ってことじゃないかな。
187 名前:デフォルトの名無しさん mailto:sage [2007/11/17(土) 23:24:01 ] >>163 明日からHaskell始めるつもりのド素人なんだけど、 関数の仮引数xがconstructor pattern(たとえばy:ys)の場合、 それはcase x of y:ys -> ...という形に変換される。 で、caseの条件式はWHNFまで評価されてしまうので、 遅延させたい時には使えない。
188 名前:186 mailto:sage [2007/11/17(土) 23:31:58 ] >>188 あ、なるほどそういうことなのか。 ありがとう。無理して答えた価値あったわ。
189 名前:163 mailto:sage [2007/11/17(土) 23:59:14 ] なんとなく理解できました。ありがとうございます。 Haskellの考え方に慣れるまでまだ時間がかかりそうですorz
190 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 00:28:05 ] sequence :: Monad m => [m a] -> m [a] sequence = foldr mcons (return []) where mcons p q = p >>= \x -> q >>= \y -> return (x:y) ↑のsequenceの定義を見るとfoldrが使われているんですが、それだと sequence [putStr "foo", putStr "bar"] の場合リストの後ろの方、 つまりputStr "bar"の方が先に評価されるのに、実際には fooの方が先に出力されてしまいます。どうして後ろからではなく、先頭から 評価されるんでしょうか?
191 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 00:55:14 ] 式の評価順とIOモナドの実行順は別物。
192 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 01:04:47 ] sequence [A, B, C] = A `mcons` (B `mcons` (C `mcons` (return []))) = A >>= (\x -> (B `mcons` (C `mcons` (return []))) >>= \y -> return (x:y)) よってA, B, Cの順にエフェクトが出る。
193 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 01:17:35 ] >>178 Haskell今日始めた人なんだけど その最適化の一環としてディスパッチが省略された場合ってのは C++でいうとtemplateによってコード生成された状態と考えていいんですかね
194 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 02:12:23 ] main = putStr "hoge" >>= \x -> putStr "foo" >>= \y -> return x main = putStr "hoge" >>= \x -> putStr "foo" >>= \y -> return y main = putStr "hoge" >>= \x -> putStr "foo" >>= \y -> return "bar" ↑のように最後にreturnさえすればエラーにならずhogefooと出力されるということは、 IOモナドはMaybeモナドやListモナドと違って、最後に何を返すかではなく、 動作をどういう順に行うのかを決めるための仕組みだと考えればいいんでしょうか?
195 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 08:09:29 ] >>193 そんな感じ。 >>194 何を返すかによってmainの型が違う。 上の二例ではIO ()で、最後の例だとIO String。 両方コンパイルが通るのは、mainの型はIO αという形なら何でもよく、 生成されたα型の値は無視されることになってるから。
196 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 13:45:25 ] >>178 実行時にならないとどのインスタンスのコードが実行されるか 静的に決まらない場合ってどんな場合??
197 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 13:51:59 ] >>196 クラスのインスタンス一般に対して書かれた関数は全部そう。例えば、 double :: (Num a) => a -> a double x = x + x こんな関数を定義したら、これをコンパイルする時点ではどの(+)を使うべきか決まらない。
198 名前:193 mailto:sage [2007/11/18(日) 13:56:54 ] >>197 その関数doubleに対して具体的に値を入れたときに コード生成される(静的に生成?)んじゃないんですかね? 頭がC++脳なのでtemplateのことばっかり頭に浮かんでしまうんですがね…
199 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 14:08:31 ] >>198 少なくともGHCやJHCならdoubleが定義されたモジュールをコンパイルする時点でコードを生成する。 そうじゃないと、doubleを使う度に毎回doubleをコンパイルすることになって、 分割コンパイルの恩恵が薄れる。(C++はあえてこれをやってるわけだが) それから、Haskellの仕様上、完全に静的に済ますわけにはいけない。 newtype P a = P a deriving Show nq :: (Show a) => Int -> a -> String nq 0 x = show x nq n x = nq (n-1) (P x) こういう関数をtemplate式でコンパイルしようとしたら、無限にnqのインスタンスを生成する必要がある。 あと、実際にはdoubleのような小さい関数はインライン化されるので、ディスパッチが省略される可能性はある。
200 名前:196 mailto:sage [2007/11/18(日) 14:27:36 ] >>199 なるほど、値(この場合Int)に依存してどういうインスタンスのコードが 実行されるかが決定する場合があるってことか
201 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 14:34:20 ] 1:2:3:[] -> [1,2,3] ↑がこうなるのはわかるんですが 1:2:3 -> ? とやった場合はどんなデータができるんでしょうか?
202 名前:186 mailto:sage [2007/11/18(日) 14:42:10 ] 3はリスト型じゃないからエラーになるんじゃないかな?
203 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 14:43:06 ] あ、名前欄消すの忘れてた……
204 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 14:46:12 ] >>201 (:) :: a -> [a] -> [a]
205 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 14:48:27 ] >>201 やってみりゃいいじゃん。それで挙動に疑問があったらここでもう一度聞いてみな。
206 名前:201 mailto:sage [2007/11/18(日) 15:25:47 ] やってみたんですがテキストに書いてコンパイルしようとするとエラーに なるのにghciで:t 1:2とやると 1:2 :: (Num t, Num [t]) => [t] というなんだかよくわからないメッセージが出ます。 :tだと型チェックしないのかなと思ったんですが :t putStr 1 とやると今度はきちんとエラーが出ます。 ・1:2 :: (Num t, Num [t]) => [t] は一体どういう意味なのか ・なんで:t 1:2はエラーにならないのに:t putStr 1はエラーになるのか ↑2つになる理由は何故なんでしょうか?
207 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 15:43:17 ] >>206 GHCは型クラス周辺を微妙に拡張してるからそのせいだろう。 Haskell98では(Num [t])という文脈はありえない。 Hugsで :t 1:2 と入れたらエラーが出たし。
208 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 15:44:43 ] ghcはIOの実装も特殊なんだよなー
209 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 15:53:43 ] 一応解説。 Haskellでは1とか7とかの整数リテラルは(Num a) => aという型を与えられる。 つまりNumのインスタンスなら何にでもなり得る。具体的にはIntでもIntegerでもRationalでもいいし、 未知のユーザー定義型でもいい。 「1:2」という式では、とりあえず「1」の型をtと書くと、整数リテラルだから(Num t)という制約が必要。 (:)の右辺の型は左辺の型のリストだから、「2」の型は[t]。これも整数リテラルだから制約(Num [t])も要る。 式全体の型は右辺と同じで[t]だから、結果として(Num t, Num [t]) => [t]になる。
210 名前:201 mailto:sage [2007/11/18(日) 16:16:46 ] やっと理解できました。ありがとうございます。
211 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 16:19:47 ] なるほど、どこかで instance Num [Int] のようなことが 書かれていないとも限らない、ということですか。
212 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 16:44:20 ] すいません 初歩的な質問でごめんなさい。 main = do cs <- getContents putStr.unlines $ lines cs これはコンパイル通るんですが main = do cs <- getContents putStr.unlines.lines cs これは通りませんでした…これって何故なんですか? てっきりlinesとunlinesというのは対になってるもんだと思ってたんですが…
213 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 16:50:06 ] putStr.unlines.lines $ cs なら通るよ。 関数適用とか演算子の優先順位の問題だね。 f $ g x == f . g $ x /= f . g x
214 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 16:55:54 ] うろ覚えだが関数抽象より関数適用のほうが優先されるので、 「putStr.unlines.lines cs」の部分が putStr.unlines.(lines cs) って解釈されるはず main = do cs <- getContents (putStr.unlines.lines) cs ならたぶん通る
215 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 16:58:16 ] 二項演算子の周りにはスペースを入れようぜw
216 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 17:00:37 ] C言語で、関数と括弧の間にスペース空ける人?
217 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 17:09:39 ] いや、そこは詰める まあ>>215 をあまり真に受けないでくれ
218 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 17:23:42 ] (.) の周りにはスペースを入れない派なんだが f.g x.h のように関数が引数を持つ場合にやるとなんか微妙
219 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 17:25:16 ] 関数合成が関数適用より優先度低いのが許せない。 こう決めた理由はあるの?
220 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 17:25:37 ] Haskellの解説文を読んでいて、どっかで見たことある書き方だなぁと 思ったら、数学の教科書とソックリです。 つまり、Haskellは数学ができる人向けってことでしょうか?
221 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 17:31:13 ] >>213-214 うお、通りました。ありがとうございます。 関数合成と関数適用の優先順位の問題だったんですね。
222 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 18:15:00 ] >>219 関数適用最強の原則を守るためじゃないか? 俺は現状で満足だ。 map (fromMaybe 0 . fst) xs とか書けるし。
223 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 18:34:32 ] >>219 うざい括弧をつけなくて済む
224 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 20:16:16 ] (f.g) x ↑↑うざい括弧
225 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 20:23:03 ] f.g $ xじゃね?
226 名前:デフォルトの名無しさん mailto:sage [2007/11/18(日) 20:42:38 ] >>224 C言語風には f(g(x)) うざくない?
227 名前:デフォルトの名無しさん mailto:sage [2007/11/19(月) 03:14:41 ] hpcgi2.nifty.com/1to100pen/wiki/wiki.cgi?p=%CB%E8%C6%FCHaskell このページの2007-07-04の日記を参考にプログラムを書いているのですが これで横型探索できる理屈がまったくわかりません
228 名前:デフォルトの名無しさん mailto:sage [2007/11/19(月) 03:39:03 ] Stateモナドについて質問なんですが instance Monad (State s) where m >>= k = State $ \s -> let (a, s') = runState m s in runState (k a) s' ↑の式でm >>= k が m >> kなら、右辺は State $ \s -> let (a, s') = runState m s in runState k s' ((k a)がkだけになる) という風になると考えていいんでしょうか?
229 名前:227 mailto:sage [2007/11/19(月) 04:04:21 ] 227ですが一応目処が立ちました。
230 名前:デフォルトの名無しさん mailto:sage [2007/11/19(月) 04:24:37 ] >>228 それでOK。 ただm >>= kとm >> kのkはそれぞれ別の型だってことに注意。 m1 >> m2 = m1 >>= const m2 なので k=const m2 と考えると runState (k a) s' = runState ((const m2) a) s' = runState m2 s'
231 名前:228 mailto:sage [2007/11/19(月) 10:59:03 ] うーん、難しい >>=が一つだけならなんとか頭で理解できるんですが>>=が二つ以上ならんでいたり do式で表されていたりすると脳味噌が追い付きませんorz
232 名前:143 mailto:sage [2007/11/19(月) 23:12:23 ] *GHC-6.6.1のクロスコンパイルについて公式ページのwikiに書いてない部分* <ターゲット、ホストに共通> デフォルトサーチパスにGNU MPがない場合は--with-gmp-{includes,libraries}で指定する必要があるが、 途中からこの指定(ライブラリサーチパス)を見てくれなくなる上、 できあがったGHCでも-Lオプションを指定しなければいけなくなるので (少なくともlibgmp.so.*かlibgmp.aファイルのどちらかを)デフォルトサーチパスにシンボリックリンクしておくほうがいい。 <ホスト> ghc-6.6.1/Makefileの echo ghc-$(ProjectVersion)/libraries/haskell-src/Language/Haskell/Parser.hs >> hc-files-to-go という行を削除またはコメントアウトする必要がある。 libraries/Cabal/cabal-setup/CabalSetup.hsが作られないので、 cd compiler && make boot && makeの後、 cd libraries/Cabal/cabal-setup rm CabalSetup.{o,hi} cabalsetup ../../../compiler/ghc-inplace -H16m -O -H32m -package Cabal -c CabalSetup.hs -o CabalSetup.o -ohi CabalSetup.hi -keep-hc-files ../../../compiler/ghc-inplace -o cabal-setup -H16m -O -H32m -package Cabal CabalSetup.o する必要がある。 make hc-file-bundle Project=Ghcの前に、 make -C rts AutoApply_thr.hc AutoApply_thr_p.hc AutoApply_debug.hc AutoApply_thr_debug.hc する必要がある。 続く
233 名前:143 mailto:sage [2007/11/19(月) 23:14:33 ] *GHC-6.6.1のクロスコンパイルについて公式ページのwikiに書いてない部分* 続き <ターゲット> いきなり/usr/localにインストールするのではなく、stage1のためのディレクトリにインストールして、 それを利用してもう一度ghcをビルドしたほうがいいと思われる。 *-hc-tar.gzをソースツリーにコピーするのではなく、展開されるghc-6.6.1を手動でソースツリーに上書きする必要がある。 distrib以下のスクリプトに実行権限を与える必要がある。 hc-buildが完了した後、 cd compiler rm -f *.hs-incl make primop-can-fail.hs-incl primop-commutable.hs-incl primop-data-decl.hs-incl primop-has-side-effects.hs-incl primop-list.hs-incl primop-needs-wrapper.hs-inc l primop-out-of-line.hs-incl primop-primop-info.hs-incl primop-strictness.hs-inc l primop-tag.hs-incl primop-usage.hs-incl find . -name \*.o -exec rm {} \; make boot stage=1 && gmake stage=1 cd .. make install stage=1 で完了。 ちなみにザウルスのOpenBSD上では16MB以上のテキストセグメントがある実行ファイルは実行できないので テキストセグメントを32MBに拡張したカーネルを使用しなければビルドできませんでした。 GNU makeがmakeという名前以外(gmakeなど)でインストールされている場合は、適宜読み替えてください。 かなり効率の悪い方法なので、Makefile等をちゃんと読めばもっと最適化できると思います。 古いGHCで新しいGHCをビルドするのはうまくいきますが、 新しいGHCで古いGHCをビルドするのはなかなかうまくいきませんね。
234 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 08:39:00 ] 一度評価された式をもう一度評価しようとする場合って、再度最初から評価しなおすんですか? 例えば add x y = x + y という関数があって、一度 add 1 2 という式を評価した後もう一度 add 1 2 を評価しようとするとき、内部では律儀に 1 + 2 を行うんでしょうか?それとも add 1 2 = 3 みたいな式が内部で作られてたりするんでしょうか?
235 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 09:30:04 ] ↑の場合は俺も知りたいです 俺が知ってるのは f x a b c = a*x*x + b*x * c という関数に対して f (1+2) 3 4 5 と呼び出した場合に1+2が1度しか評価されないことくらい…
236 名前:デフォルトの名無しさん [2007/11/20(火) 10:20:01 ] >>234 Haskellの規格では規定されてないけど、普通は評価しなおす。 関数を全部メモ化していたら、救いようのないメモリリークが起こるはず。ただし、 map (\x -> x * add 1 2) xs のようなコードが最適化されて let _z = add 1 2 in map (\x -> x * _z) xs になって、add 1 2が一回しか計算されない、という場合はある。
237 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 11:41:31 ] >>234-235 コンパイラのコンパイルオプションによっても動作が違うかな import System.IO.Unsafe f n=seq (unsafePerformIO $ putStrLn "hello") n a=f 1+f 1 main=print a のようなコードだとGHC6.6.1の場合で最適化なしの場合とありの場合でhelloの表示回数が違ったりする。
238 名前:237 mailto:sage [2007/11/20(火) 11:44:46 ] 追記 a=f 1+f 2 でも最適化ありで1回表示、 無しで2回表示でした。
239 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 18:31:21 ] 質問なのですが、 ドラキュラとかが眠ってそうな感じの、棺おけ型のベッドというのは市販されているのでしょうか? 冬の暖房の時期に、部屋ごと暖めるのでは効率が悪いので、棺おけの中だけ温度調節できれば コスト安になると思ったのです。 また、フタをつけるので静かですし、明かりもシャットアウトできてよいと思うのです。
240 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 19:04:23 ] ドラキュラとかが眠ってそうな感じの、棺おけ型のベッドというのは市販されているのでしょうか? (計算をデフォルトで遅延させる機能のある、関数型のプログラム言語は市販されているのでしょうか?) 冬の暖房の時期に、部屋ごと暖めるのでは効率が悪いので、 (評価されない可能性のある式を正格に評価するのは効率が悪いので) 棺おけの中だけ温度調節できればコスト安になると思ったのです。 (必要になってから評価できれば計算コストを削減できると思ったのです。) また、フタをつけるので静かですし、明かりもシャットアウトできてよいと思うのです。 (一度評価されればメモ化されるので計算量が少なくなりますし、バグの混入もシャットアウトできてよいと思うのです。) 答え:Haskellは無料で公開されています こうですか!? わかりません!
241 名前:デフォルトの名無しさん mailto:sage [2007/11/20(火) 19:27:37 ] 感動した
242 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 04:31:54 ] 質問です GHC6.8.1にはHGL入ってないんですか?
243 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 01:59:38 ] Windowsアプリ作っていて気づいたんだが、 Win32モジュールにはSetLayeredWindowAttributesのラッパは入ってないんだな・・ 自作するしかないんだろうか。
244 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 07:26:41 ] 書いてパッチを送るんだ!
245 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 12:20:00 ] >>244 >書いてパッチを送るんだ! いや、これってwindows2000以降の機能で、Win32モジュールに入れるべきかどうか正直迷うんだよね。
246 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:16:48 ] Windows2000以降のラッパをまとめたWin32exモジュールを作ったので公開しました。 ツッコミなどよろしく。
247 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 09:58:22 ] >>245 Windowsに詳しくないので間違ってたら済まんが、2000以降のみの関数も 普通にwin32パッケージに入ってないか?setConsoleCPとかfindFirstChangeNotificationとか。 >>246 どこに置いたかも書けよw
248 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 10:06:51 ] 246はPeyton Jonesだ。 場所は、わかるだろ。
249 名前:デフォルトの名無しさん mailto:sage [2007/11/26(月) 23:05:20 ] 関数型言語はマルチコア時代にフィットしているという話を聞いたことがあります。 既存の流行している言語は対応できてないと。 これはどういう理由でしょうか?遅延評価とか、その辺のことを指しているんでしょうか。
250 名前:デフォルトの名無しさん mailto:sage [2007/11/26(月) 23:13:40 ] 知らんけどミュータブルな値があるとスレッドセーフにならないとかそういうへんの話じゃね?
251 名前:デフォルトの名無しさん [2007/11/26(月) 23:23:18 ] MapReduce の「副作用が無ければ無限にスケールする」というのが 一人歩きしてるだけじゃないかな。実際には何をするにも副作用は あるし、MapReduce だって Reduce の作業はスケーラビリティが 殆ど無いか少ない。関数型言語には副作用が無いというのと同じ様な 勘違い。ただ副作用が無い=スケールする部分を奇麗に切り出せる のであれば有用ではある。
252 名前:デフォルトの名無しさん mailto:sage [2007/11/27(火) 11:43:41 ] ああいう大規模データパラレルとマルチコアはあんまり関係ないじゃん。 >>249 の話は伝聞なんで雲を掴むような話だけど。
253 名前:249 mailto:sage [2007/11/27(火) 11:48:13 ] ありがとうございます。透過参照性がスレッドセーフというのはよく分かります。 遅延評価っていうのは、別に関係ないんでしょうか。何かそっちの話を聞いた ことがあるんです。自分の初心者脳では、正格では無限のリソースを前提に した関数を書けないが、Haskellのような言語だと記述可能、とか思ったのですが、 ちょっと頭悪いですか?w
254 名前:デフォルトの名無しさん mailto:sage [2007/11/27(火) 12:16:38 ] 遅延評価や投機実行をうまく使えば、 CPUコアの利用効率を上げられますが、 それには頭のいいスケジューラが必要なわけで。 例えば、 www.fixstars.com/Grid/pukiwiki/index.php?MapReduce にプチ解説があるようなstragglersの問題。 ただ実行順序が規定されてないので、 工夫する余地がまだまだ残されているとは言えると思う。 Erlangのような言語が、あまりpure functionalじゃないとはいえ、 一通りの実績を上げていますし。 また、プログラマがスケジューラに自由を与えるような プログラミングスタイルを強制されているという見方もあると思う。
255 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 10:41:19 ] F#のスレは毎日更新されてますが、こちらは静かですね・・・ 関数型で今イチバン売れ筋なのはF#なんですかね。
256 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 17:36:48 ] Haskell始めてから3週間目の今の感想。 ・概念的にはMonadよりArrowのほうが分かりやすいんじゃないか?とか。 ・Monadって何?って聞かれるとなんと答えていいかわからないが、 Arrowなら『矢印をカプセル化したようなもの』と言える。 あとは適当に結合演算とか普通の関数をアロー化する演算とか実装していけばおk。 脳内のイメージも矢印をつないでいくだけだし。 Monadをイメージしようとしてもなんかいまいちピンとこない……。 bindにやる夫関数とか適当に名前を付けて無理矢理イメージしたけど。 ・Monadのbind演算子(>>=)はm a -> (a -> m b) -> m bで非対称的。 Arrowの(>>>)はa b c -> a c d -> a b dで比較的対称性があって気持ちよい。 ・Arrowは『計算を結合』しているのが自明的に表現されてる。 Monadは別にそうは見えない。……値と計算を結合なのか?意味わかんね。 ・そもそも非対称な二項中置演算子はイマイチ気に入らない。 リスト結合演算子とか`elem`とかは仕方ないけど、せめてあまり高階にしてほしくない ・Monadの計算部(a -> m b)は結構重要なパーツの一つなのに、名前が付いてない。 だから『モナドを返す関数』としかいえねえ。 しかもbindした後にはその返り値とは(型は同じだけど)別の奴が帰ってくる。無駄に混乱。 その点Arrowは計算部がずばり『Arrow』。カプセル化されていて美しい。 ・Monadは(>>=)は左から右へ流すように使えるが 普通の関数は右から左。もちろんliftMとかも右から左。 (=<<)も右から左。しかし関数を拡張して適用するという見方で見るとこっちが自然という謎さ。 結局どっちからどっちへ読むべきか迷う場所が多く、思考停止してしまう。 ArrowだったらArrowとして結合されている部分は左から右。 普通の関数は右から左で思考が自然に切り分けられる。
257 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 17:37:32 ] ・Monadでポイントフリースタイルをやろうとするとかなりキモくなるよね。 Arrowはまあ基本的にポイントフリーな感じがするし、普通の関数と分けられていいんじゃない? ・Arrowの構造を作ったりする関数は基本的にArrowだけを返す。 Monadの関数はなんかリストとかに入ってたりして気味が悪い。モナドのリストって、最中十個入りじゃないんだから。 ・Arrowの構造を作る関数はキチンと構造を作ってるように見える。 Monadの場合は解読に時間がかかる。なんのためにこんな書き方をしてるんだろうとか……。 ・ArrowでStateを自作してみたら比較的分かりやすかった。 Monadのは今見ても訳が分からん。というかMonadの対象が関数って何だよ。 ・Monadに慣れ親しんでる人はMonadを扱うのに苦労しないだろうから、 簡単なものなら短い表記が出来るMonadのほうがいいんだろう。 しかし、初心者にいきなり教えるのならArrowのほうが直感的。 ポイントフリースタイルを使いまくってムツカシイことさえしなければ。 ・Arrow講座みたいな入門編とかでArrowを書くとき、 関数がそのままアローになるからってやたら省略しないでいただきたい。 アローな部分と普通の関数の部分が綺麗に分かれてるのがいいんだから…… それにarrってやっておけばその部分は一般のArrowでも使えるし。 SF f >>> SF g = SF (f >>> g)とか出来るからそういう書き方が出来ること自体はありがたいが。 ・arr.uncurryとかarr.constってよく出てくるけどそういう関数はないのか…… ・Arrow関係ないけどデータ構築子と型構築子が同じ名前って混乱するな。時々イラっとくる。 ・aとかbとか何を表してんのか直感的じゃねえよ。型変数だったり、引数だったり…… fって名前だから関数かと思いきやArrowだったり。 ネーミング規約みたいなものはないのか…… Arrowが引数で来たときの名前の付け方とかおもいつかねえけど。 ・そろそろふつける買おうかな……。 ・初心者のくせに身の程をわきまえない長文失礼しました……
258 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 17:42:34 ] >>257 > ・Monadでポイントフリースタイルをやろうとするとかなりキモくなるよね。 もう少し他人のコードを読んでいくと感覚がつかめてくると思いますよ
259 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 18:11:18 ] モナドのリストを返す関数なんてそんなに使うか? しかし「モナドのリスト」って言い方は何か違和感あるな。 [IO]みたいなのを想像してしまう。
260 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 18:16:50 ] 俺のポリシーではIOはmain内でしか使わない
261 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 18:25:06 ] >>258 把握。 >>259 ライブラリを見返してるけどそこまではなかったかも……。 初めて見たときに比べればそこまで疲れないし。 やっぱり慣れの問題なんだろうか。『モナドを返す関数』が普通の関数と同じ地位にいるのがイマイチだけど。 引数の数でバージョンがいくつもあったりするのもなんかいただけない。 でもやっぱり慣れれば気にならなくなるんだろうな……。 なんかJavaやったらCのポインタが理解できた時の気持ちを思い出した。(違うか)
262 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 18:30:02 ] モナドなんてステートとIOとリストとMaybe以外はほとんどつかわねーぜ
263 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 18:30:44 ] IORefもつかうか。
264 名前:デフォルトの名無しさん mailto:sage [2007/12/06(木) 18:38:36 ] a0 -> a1 -> ... -> m bの形の関数を呼ぶのにはmonadic functionという名前が使えるはず。 日本語だと「モナドな関数」か。 俺のコードの大部分はモナドな関数になってるな。 普通の関数より書きにくいから嫌なんだが、変更に強いコードにするために仕方なく。
265 名前:デフォルトの名無しさん [2007/12/08(土) 12:05:09 ] やさしいHaskell入門での質問です。 www.sampou.org/haskell/tutorial-j/classes.html > (ここで、同値性といっているのは、「値同値性」のことです。 > 対照的な概念としては、「ポインタ同値性」というのがあります。 > たとえば、Java 言語の == です。 > ポインタ同値性は参照透明性を持ちません。 > それゆえに純粋な関数型言語とは相性がよくありません。) なぜポインタ同値性は参照透明性を持たないのですか?
266 名前:デフォルトの名無しさん mailto:sage [2007/12/08(土) 12:26:42 ] >>265 ポインタ同値をテストする関数eqがあったとすると、 let v = [1,2] in eq v v はTrue。一方、vを展開して eq [1,2] [1,2] とするとFalseになるかもしれない。 参照透過って言うのはそもそも、こういう展開をしても プログラムの意味が変わらないってことだから、 eqによって参照透過性が破られたと言える。
267 名前:265 mailto:sage [2007/12/08(土) 12:37:55 ] >>266 おー!なるほど。わかりやすい説明ありがとう。 [1,2] が複数箇所に出現する場合、メモリ上に別々に配置されるかもしれないわけですね。 勉強になりました。
268 名前:デフォルトの名無しさん mailto:sage [2007/12/09(日) 15:29:39 ] 『A a』っていう表記が使われる場所によって Aは型構築子、全体は多相型、aはパラメータ Aはデータ構築子、全体はデータ構造、aはその中身 aは型クラスAのインスタンス、何かの型の一部 って変わるのがちょっとわかりにくいね。もうちっとなんとかならんか。
269 名前:デフォルトの名無しさん [2007/12/09(日) 21:35:19 ] Haskell勉強してなくてよくわからないんですが、 乱数生成器をsplitしていくつかにしてseed固定で乱数を作れといわれました。 どう作ればいいんでしょうか? 初歩的な質問だったらすみません。
270 名前:デフォルトの名無しさん mailto:sage [2007/12/10(月) 00:51:19 ] 日本語でおk
271 名前:デフォルトの名無しさん mailto:sage [2007/12/10(月) 15:07:15 ] 無限リストって便利だけど、末尾を正格に要求する関数について型安全じゃないよね。 でも無限リスト型を再定義するとリストに関して作ったすべての関数について委譲関数を作んなきゃいけなくて現実的じゃない。 結局これは妥協するしかないのか?それともなんらかのテクニックで回避できる?
272 名前:デフォルトの名無しさん mailto:sage [2007/12/11(火) 10:46:48 ] >>271 日本語でおk
273 名前:デフォルトの名無しさん mailto:sage [2007/12/11(火) 10:52:25 ] >>271 俺の知る限り、妥協するしかない
274 名前:デフォルトの名無しさん mailto:sage [2007/12/11(火) 12:46:45 ] >>271 評価がとまらないだけで型安全だよ。
275 名前:デフォルトの名無しさん mailto:sage [2007/12/11(火) 13:17:06 ] そう言えば、厳密に言うと無限ループでも型安全なんだな でも全域関数でない関数が厄介なことは事実だから、何か呼び名が欲しい