関数型プログラミング言語Haskell Part33
■ このスレッドは過去ログ倉庫に格納されています
関数型プログラミング言語 Haskell について語るスレです。 Haskell Language(公式サイト) https://www.haskell.org/ 日本Haskellユーザーグループ - Haskell-jp https://haskell.jp/ 前スレ 関数型プログラミング言語Haskell Part32 https://mevius.5ch.net/test/read.cgi/tech/1548720347/ Haskellスレってワードサラダbotに荒らされてるのか haskellでアクションって言葉よく出てくるけど定義なに? >>181 HaskellでActionという用語をみたことが俺はないけど、Haskell直系の子孫のPureScriptだと 型注釈の->の右辺にEffectがある関数をアクションと定義するそうだ。 EffectはHaskellでいうIOに対応すると思ってもらえたらいい。 ちなみに->の左辺にEffectがある関数をハンドラという。 -- アクション throwException :: forall a. Error -> Effect a -- ハンドラ catchException :: forall a. (Error -> Effect a) -> Effect a -> Effect a むしろ>>188-189 がどういうことなのかわからない CabalのドキュメントのSecure repository のところ、 root.jsonのkey idを省略するのはお勧めしないとか書いてるけど、 なにかしないといけないの? このスレにはHaskellerなんかいないということがよくわかるな 本当に言語に詳しい奴ってのはその言語の弱点をしっかりおさえてるもんよ。 IO がオルタナティヴになったのって最近なのか Aizu Online Judge のGHCだとコンパイルエラーになる let [a,b,c,d] = bokunofunction in 〜 このリストってWHNFにならないのな 目的は二つ 式を評価し過ぎないこと 副作用を実行し過ぎないこと 手段はただ一つ 最外簡約 haskellでコロナ感染シミュ作るやつ誰もおらんのか? codewarの問題をHaskellで解いてみてるんだけど 、12000msタイムアウト多発する リスト内包表記とか再帰はHaskellerはあんまり使わないの? nに含まれる素因数とかすぐタイムアウトする >>199 arithmoiとかのライブラリ使うとめっちゃ速いよ ソースを見てみるといいかも あと、prime factorization haskell とかをキーワードにして検索してみるとか Haskell で競プロ辛い・・・ 200000個の整数読み込んで処理するような問題だとMLEになりがちだ 本当にそんなに使ってるのかよ・・・疑わしいなぁ ランタイムがとりあえずあるだけ使おうとして、足りなくなったらもう要らない空間を探して、そこに上書きするようにしてるの? だとすると、とりあえずあるだけ使おう期間の段階で上限ぶっちぎってるってことかね もしかして GHC「記憶域ください」 競プロシステム「あなたは上限なのでもうあげません」 GHC「仕方ないな、じゃあガベージコレクションしてなんとかやりくりしよう」 ではなくて GHC「記憶域ください」 競プロシステム「どうぞどうぞ」 GHC「どうも」 競プロシステム「はいそれは毒まんじゅうです。今のでMLEです」 GHC「えっ!!!!」 こうなんじゃないか? ソースコードで「メモリ使用はは150MB以内で巧くやりくりしろ」とかって制限の指示できないんですか? Haskellで競プロやるテクをまとめた同人誌があったような mleってなに? Maximum likelihood estimation しか思いつかん 競プロ mle でググってみた MLE メモリリミットエラー(Memory Limit Error)の略 提出したプログラムが許可された以上のメモリを使用したときに出る (一部のコンテストで採用されている表現) >>201 とりあえずローカルでプロファイル取って実行してみると スペースリークや大量のGCの原因が推定できるはず (「Haskell プロファイラ」とかでぐぐって) 未評価のサンクが大量に積み上がっているとか、 イミュータブルな連結リストの使い方が悪くて 大量の一時リストを作ってしまっているとか あたりじゃないかと想像してみる タイムアウトのやつ この問題やってて ttps://www.codewars.com/kata/54d496788776e49e6b00052f/train/haskell 通らないコードがこれ sumOfDivided :: [Integer] -> [(Integer, Integer)] sumOfDivided xs = map (\x -> (x,foldr (+) 0 (filter ((==0).(flip rem x) ) xs)) ) $ prime_factors ( product xs) 2 where prime_factors 1 _ = [] prime_factors m n | rem m n == 0 = n : (prime_factors (quot m n) $ n+1) | otherwise = prime_factors m $ n+1 こういう感じでコード組み立てるんだけど、他の問題でもしょっちゅうタイムアウト起こしてる 応答の速いコードにするにはどんなふうに変えていけばいいかを知りたい cで言うと値コピーしてソートしないでポインタでソートすると速いみたいな >>208 どう改善すればいいかはすぐにはわからないが prime_factors関数は末尾再帰ではない再帰をしているから容易にスペースリークしそうな感じはする できるだけリストを避けて 読み込みもByteString 版 getContents と readInt の組み合わせで高速化 そして困ったときの Data.Sequence 様やで! C系提出者は軒並み 0.1 s で処理を終えている中、220MB 1.9 s 弱かけてなんとか致命傷でかいくぐった 制限超過してる気がするが、マイナー言語へのアファーマティブアクションかな? くぅ〜疲れましたw これにて AC です! >>208 prime_factorsだけど quotRem なら一回で両方得られる 探索は3から+2ずつ探すべき n が√m を超えてしまったら探索を打ち切るべき リストの整数全部に出てくる素因数を予めリストアップしたいんだろうけど そのprime_factorsだと絶対に素因数が存在しない、(2を除く)偶数空間と√mの後の空間をmに達するまで探していてとてもとても無駄 この無駄はmが大きいほど酷いことになるが、見事に君のコードはproductなんてしてmを巨大化させている 例えば、1000000 の素因数は少なくとも1000 以降は存在しないのに1001, 1002, 1003, ... , 999998, 999999, 1000000 まで探すところを想像してみて 一目気づいたのはそんなところかね。先ずはそこを直してから一局といったところか >>207 まあ最終手段はそうなるんでしょうね しかし早すぎる段階での最適化はたいてい悪手って言われてるし その前に、アルゴリズムの選定が間違ってるんではとなって、あれこれ作戦変えて いつしか通るわけです。すると結局いつまで経ってもプロファイリングを練習する機会が来ないんですよね あ、いや、あれこれ作戦変えるヒントを得る為にプロファイリングするのか・・・ やっぱり手を出してみるか 異世界人「アルゴリズムをあれこれ変える」 主人公「言語をあれこれ変えてみよう」 時間とメモリ両面のcomplexity考えるのは最適化以前の話 >>211 39の素因数って3,13よね? √39が6くらいだから探索区間は√mじゃ不十分かなって でも確かに偶数はいらないから2:[3,5..]でいいね 全部の素因数のリスト作るのに全部掛け合わせて処理はひどいなと見直して思った リストは早くするなら使わない方針なのね Quatremとリスト以外(sequenceが代替?)調べて組み込んでみようかな お礼書き忘れたすみません 回答ありがとうございますなんとか通ってもらいます >>216 なんの話かよく知らないけど39を素因数分解してるのなら、 約数として3が見つかったら、その時点でもう39が素数じゃないことが判明するから、13を調べる必要ないよ √39以下の数字調べればオッケー 間違えた 「素因数分解してるのなら」じゃなくて「素数判定してるのなら」だった >>208 計算速度や使用メモリ量以前に、解が正しくないよ。 試しに sumOfDivided [8] やってみ。 もう少し言うと、prime_factors 関数がおかしい。 関数名に相応しくない計算をしていられる。 まずは、必要な個数の正しい素数列を作ることを考えた方がいいと思うぞ。 >>216 あ、説明で嘘を吐いてしまった。確かに√m以降に素因数は存在しないは偽だった それでも尚、√で打ち切っていい手筋は揺るがない。 √39より前の3を発見して、39 `quot` 3 (=13) に対して再帰的に同じことをする ただし割ることを試すのは今割り切れた素数からね(同じ素数で複数回われることもある)。 もう一回3で割ろうとして失敗し、次は√13 を超えるので打ち切って、13 は素数と判定してリストに加える だから結果として、√m 以降の素因数を取りこぼすことはない >>221 素数系のアルゴリズムは手続き的にはよく知られたものが色々あるけど それをHaskellっぽく(宣言的に)定義しろって言われると割と悩む STMonadとか使えば手続き的な実装はできるけど何かに負けた気分になる 速度あげようと思ったら、どうのように計算するかということに介入する必要があるから手続き的になるのはしょうがないのでは 魔法を使える主人公がなぜか銃を乱射するというマナー違反 を許せない真面目系脇役の魅力 騎士道はCで書くなど、汚い真似をして勝つことを認めていない ごきげんよう、高貴なるhaskellプログラマの皆様方 今日も可憐におプログラミングですことよ ほほほ haskellマスターすると新型コロナにかからないってよ C言語プログラムなどを実行すると電磁波の影響で身体への副作用が発生するからな 副作用を抑え人間本来の自然な免疫力を高めるのがhaskell >>229 我慢できずにモナドに手を出して感染する事例が後を立たない モナドは自粛すべきと何度も言われているのに 屁理屈をこねて手を出す者が多すぎる 本当にHaskellに副作用がないのだと詭弁を弄せずごり押しするのならば 絶対にモナドをやるべきではないと言われている モナドを「やる」ってなんだよw モナドを禁止薬物か何かと勘違いしてるのか? すべての人間は二分される すなわち「モナドである」人間と、そうでない人間、だ 俺はモナド お前はモナドではない 「上」で待ってるで C言語プログラムなどを実行するとストレスの影響で毛髪への副作用が発生するからな 脱毛を抑え人間本来の自然な論理を書けるのがhaskell >>233 モナドに使われてるやつほど、自分はモナドを使ってると勘違いするよなw モナドを使う時、モナドもまたあなたを使っているのだ [状態モナド](https://wiki.haskell.org/State_Monad )を [随伴](https://en.wikipedia.org/wiki/Adjoint_functors ) on Rails に乗せてみる。 ``` code type W x a b = (a, x) -> (b, x) type S x a b = a -> x -> (b, x) in_away :: W x c d -> W x b c -> W x a b -> W x a d in_away cd bc ab = cd . bc . ab in_home :: S x c d -> S x b c -> S x a b -> S x a d -- in_home cd bc ab = to_home $ in_away (to_away cd) (to_away bc) (to_away ab) where -- in_home cd bc ab = ext cd . ext bc . ab where in_home cd bc ab a = new a %>>=% ab %>>=% bc %>>=% cd where (%>>=%) = flip ext ext = to_home_fmap . to_away new = to_home id to_home_fmap = (.) to_home = curry to_away = uncurry ``` `to_home`が[記事](https://en.wikipedia.org/wiki/Adjoint_functors )での`Phi` に、`ext`が[Kleisliのスター](https://en.wikipedia.org/wiki/Kleisli_category ) に対応する。`in_away`は通常の関数の合成で、`in_home`はそれを黒魔術に 翻訳している。 [継続モナド](https://wiki.haskell.org/Continuation )も随伴で書ける。 ``` code type O x a b = (b -> x) -> a -> x type C x a b = a -> (b -> x) -> x in_away :: O x c d -> O x b c -> O x a b -> O x a d in_away cd bc ab = cd %.% bc %.% ab where (%.%) = flip (.) in_home :: C x c d -> C x b c -> C x a b -> C x a d -- in_home cd bc ab = to_home $ in_away (to_away cd) (to_away bc) (to_away ab) where -- in_home cd bc ab = ext cd . ext bc . ab where in_home cd bc ab a = new a %>>=% ab %>>=% bc %>>=% cd where (%>>=%) = flip ext ext = to_home_fmap . to_away new = to_home id to_home_fmap = flip (.) to_home = flip to_away = flip ``` 厳密には、`flip`は随伴ではないが、`Set^op (a, b)`と`Set (b, a)`が集合 として同型になることを使うと、実質的な随伴の役割を果たす。 その話題は伸びない。このスレにはHaskellerいないからコード貼ったって誰も読めないし圏論を理解してるやつなんかいないから ここには数学とプログラミング両方できる人がいるようだからお聞きしたいのだけど プログラミングのクロージャーってトポロジーのクロージャーから引っ張ってきた用語なの?トポロジーの方の定義を眺めてみてもイマイチつながりが理解出来なくて この言語って純粋に理論的な側面に興味を感じてしまって、アプリ制作進まなくなるわ それよりメモリ管理の理論に興味を感じないか static変数のようなものを使えばメモリ管理と無縁のアプリ製作ができるのだが メモリ管理に興味を感じないか? → メモリ管理と無縁の〜ができるのだ ?????? メモリ管理するんじゃなかったのか? 10年以上前から同じ会話してるだろ 免疫がつくまで繰り返すんだぜこれ 低俗なねらーにはHaskellはら難しすぎたんや… メモリ管理の様な世俗的な因習に捕らわれず神の領域を安らかたらしめん為の関数型言語では無かったか 現実のハスケラ達は評価順やサンク潰しの制御のテクニックを競ってマウンティングし合ってるよ くだらない事をダベってるくらいなら、Polysemyの基礎でも勉強してろ https://sir4ur0n.github.io/ それを知るとどんな良い事があるのか、学習の動機づけをください 簡単に言えば、安全で明確でテストしやすいプログラムが書ける。 IOモナドの関数は中でどんなIOアクションでもできてしまい危険だ。 大事なファイルを上書きしようが、大音量でビープを鳴らそうが。 Polysemyに代表されるエフェクトシステムを使うと、 関数の中で使えるIOアクションの内容を関数シグネチャで制限できる。 ファイル読取アクションを宣言した関数の中では、書込や画像表示など他のIOアクションは一切できず安全だ。 また、ビジネスロジックのコードではどんなアクションをするのか(what)というレシピだけを書き、 そのアクションを実際のIOを使ってどの様に実現するか(how)は別のコードで書くことになる。 whatとhowがしっかり分かれ明確だ。 なので、ビジネスロジックのコードは純粋関数で書け、テストしやすくなる。 howのコードだけをモックに変えることもでき、これもまたテストを容易にする。 と言うようなことを例を交えて分かりやすく説明しているのが >>260 の記事だ。 目を通しました(理解できたとは言ってない) 粒度の粗い物を制限してもっと細かくして、その組み合わせで書き直すことで間違いを排除する、 (手を入れられない)既存ライブラリに対して、ぼくのかんがえたさいきょうのリファクタリングをエミュレートする基盤となるものですか? >>263 前半はその通り。 が、すまん、後半は意味が分からない。 リファクタリングをエミュレートするってどういう事? 初めて聞いたフレーズだ。 リファクタリングをする事と、リファクタリングをエミュレートする事の違いを教えてくれ。 真のリファクタリングは、設計しなおしてソースコードも書き直す事が含まれるとすると 標準ライブラリであるIOモナドの設計やソースコードを直接弄ることはできませんから、ポリ蝉版は本当にIOを再設計したわけではなく、 リファクタリングを疑似的に再現したという解釈はできないでしょうか リファクタリングの真似事なのでエミュレートと言いました >>265 なんか、私と貴方の間にリファクタリングという言葉に齟齬があるような・・・ 今までIOモナドを直接使っていたコードをPolysemyを使うようにリファクタリングすることはできるよ。 エフェクトシステムの設計者たちはそれを推奨している。 でもそれは、IOライブラリのコードが弄れないから、仕方ないので、Polysemyで擬似的に弄ったように見せましょう、 という話では全くないよ。 Polysemyってはじめてきいた Extensible effectsとは別もの? >>268 名前が違うんだし、そりゃ別物だよ。 同じエフェクトシステムというカテゴリの一員ではあるが。 どう違うかは >>260 を読んで判断してくれ。 短い記事だからすぐ読める。 IOは副作用じゃなくて作用だからハスケルは副作用が無いんだなんていってるやつ初めて見たんだけど あらかじめ宣言した型に従う作用じゃなくて 宣言していないことを勝手にやるのが副作用の弊害だから Haskellにはこの弊害が無いんだな >>271 そう言うこと。 でもIOは実質なんでもできちゃうから、かなり不安だよね。 もっとeffectを安全に取り扱いたいよね。 その解のひとつがPolysemyだよ、という話しだ。 >>270 PolysemyのブログPart1を読んで思うところがその嘲笑だけなら、 英語ドキュメントの読解にはちょっと向かないかな。 ブログを観る限り素人の書いたクソ記事だな 読む価値なし ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる