haskell-jp / atcoder-lang-updates #7

追加提案,というか皆さまの意見を聞きたいです:
strict (): 基本的なデータ型 ( Either , Maybe , and pair from base, These from these )のfield-strict version と baseに入ってる lazy IO の strict version を実装します. 元々transitive dependency に入ってて, https://haskell-jp.slack.com/archives/C014PGG641Z/p1678521681800639 = https://haskell.jp/slack-log/html/C014PGG641Z/4.html#message-1678521681.800639 あたり見てもモチベーションはありそうな気がします.しかし,リンク先の会話の主題そのものはタプルなのですが,このパッケージの Data.Strict.Tuple はペア Pair a b しかサポートしてなくて,19項までのタプル( T1 , T2 , … , T19 )をサポートしてる strict-tuple () はモジュール名が Data.Tuple.Strict でややこしい,というのがアレですね.
話を複雑にするようで申し訳ないんですが、 http://h2.jaguarpaw.co.uk/posts/nested-strict-data/ とかどうですか?
多分 https://hackage.haskell.org/package/strict-wrapper-0.0.0.0 がその実装のようです。
引用頂いたスレッドの発言の時も本当はこれを挙げたかったんですけど、うまく探せなかったもので...
あー,頭のいい実装だ.4項までのタプルしか実装がないのは残念ではありますが,結構便利そう.
あまり利用もメンテも熱心にされてなさそうなのが惜しいんですけどね。すごくいいアイディアなのに。
貫禄の Dependencies: base < 5
こういうパッケージって「古く」はならなそうに見えるので入れるのにそんなにリスクはなさそうですが,無意味に入れると収拾がつかなくなりそうという理由だけで躊躇するところはあるんですよね…
でも Haskell の競プロ提出コードなんて bang がついてない変数を思い浮かべるのが難しいくらいですし,あったら結構嬉しそうなんだよな…
strict-wrappers については, unsafe な関数が注釈なしに含まれているので導入を見合わせようかなと思います. = https://haskell-jp.slack.com/archives/C5666B6BB/p1680184874825459 でのログをご確認くだされば幸いです.
strict の Data.Strict.Tuple は Pair a b しかないですが x :!: y :!: z のようにできるのでそこまで不便ではないかもしれません。
オンラインジャッジ的な対応としては containers にある Utils.Containers.Internal.StrictPair を使うという手もありますが Show にすらなっていなくて不便ですね
@ほげやま has joined the channel
あー、とすると strict はだいぶ良さそうですか。メモリ上のレイアウトまで気にするなら strict-tuple を更に追加で入れるのも一応選択肢にはならないことは…ないのか?
あ,忘れてた.最適化をまともにperf取らずに神に祈るのが好きな私みたいな軟弱者には,`strict-containers` () のデータ型のフィールドまでstrict flagがついた containers (+unordered-containers) 実装とか見せられるとちょっと気になってしまいます。

data X = X !Int !Double
data Y = Y Int Double

を考えたときに、 case x_value of X !a !b -> ... は a, b が評価されているかを判定するコードが不要だが、
case y_value of Y !a !b -> ... において y_value のフィールドがあらゆる評価パスで評価済みだとしても、実行時に評価済みかどうかを判定するコードが消せない可能性がある、みたいなことを耳にするので…
Language Test Contestが2nd freeze (3/28)版に更新されました!

期待通り,次のコードをコードテストに投げると cabal.project.freeze ファイルを取ってこれました:

import 

main :: IO ()
main = putStr =<< readFile "/judge/submission/cabal.project.freeze"

結果は https://gist.github.com/gksato/b7d0b18e9ef8be5762fef8717737e27b#file-4-cabal-project-freeze です.

あと,全exposed modulesのインポート () を投げても実行が通ることも確認できました!

今の所,次のfreezeの時には,
• extra : 1.7.12 -> 1.7.13
• strict を追加
• インストールコマンドとコンパイルコマンドにおいて,workdirの仕様が不明だったために必要だった余計なコマンド群を除去(参照: https://docs.google.com/spreadsheets/d/1HXyOXt5bKwhKWXruzUvfMFHQtBxfZQ0047W7VVObnXI/edit#gid=1835616968&range=H67:I68)
を確定で実施するつもりでおり,
• strict-tuple の追加
• strict-containers の追加
については保留中です.
GHCについてくるライブラリ群で現環境では使えるが新環境では使えない状態のものがあるので対応しておきたいです
import Data.Binary () -- binary
import Data.Time () -- time
import System.Directory () -- directory
import System.FilePath () -- filepath
import System.Posix () -- unix
import System.Process () -- process
import Text.PrettyPrint () -- pretty

main=pure()

... Replies ...
あーそれ,(競プロに関係あるかわかんなくて)入れるか迷ってたんですよね.入れる側に一票入ったので入れることにしましょう!
あと, GHC-bundled library で現環境で使えるけど新環境では使えない,というと ghc-boot, ghc-boot-th, hpc, integer-gmp, terminfo, ghc-prim あたりもそうなはずですね.ここら辺も入れた方がいいでしょうか?

現環境は cabal install --lib を用いているので, GHC-bundled library ( で確認できます)のうち,`cabal-install <= 3.8.1.0` が Distribution.Client.CmdInstall.globalPackages 変数によって明示的に global package とみなしていたものは利用可能だったはずです.

ほかには,現環境では使用できない GHC-bundled package (一度も cabal install --lib を投げたことのない裸の ghc では使えるが,一度でも cabal install --lib を投げてしまうと top-level ghc から不可視になってしまうタイプのGHC-bundled package.`globalPackages` 変数に名前が挙がってないとそうなる)もありますが,そこら辺についてはどうしましょうか.
なるほど. Windows 環境下でないとビルドできない Win32 を除き,
• Cabal
• Cabal-syntax
• binary
• directory
• filepath
• ghc
• ghc-boot
• ghc-boot-th
• ghc-compact
• ghc-heap
• ghc-prim
• ghci
• haskelline
• hpc
• integer-gmp
• libiserv
• pretty
• process
• stm
• terminfo
• time
• unix
• xhtml
を全て追加する,ということですか. ghc-compact をただ追加するのもアレなので,
• compact
を追加してもいいかもしれませんね.

さしあたって気にすべき点は,特に ghc-prim などの ghc* 系が GHC のバージョン間で安定したAPIを提供しそうに見えない,ということでしょうか.

細かい反論としては:
• ghc とか terminfo とか本当に要るの? → 「本当に」要る要らないの線引きは難しいので,「GHC-bundled」という明確な線引きがあるのは良いこと
• ghc* 系はHackageにアップロードされていないことが多い( 「GHC-bundled version しか使えないからHackageからのダウンロードの需要がない以上,面倒だからいいよね〜」という理由なのかは知らない)ので,`cabal-plan license-report` が自動でライセンスを拾ってこれないため,License report の Human-written caveat を手書きで追加執筆しなければならないのが面倒 → 頑張れ
という点もありますが,ここら辺は簡単に再反論できるところですね.とくに「GHC-bundled」という明確な線引きがある,というのは結構な美点っぽいです.

みなさんのご意見もお聞きしたいので,よろしくお願いします.
transitive dependencies に入ってて,ちょっと便利そうなので,追加提案:
• indexed-traversable
• indexed-traversable-instances
あと, lens 系が入っているので,
• strict-containers-lens (`strict-containers` を入れるなら)
を追加提案しておきます.
... Replies ...
せっかく attoparsec と parsec が入っているなら trifecta と megaparsec を紛れ込ませたいという悪い欲望があります:sweat_smile:
あとは,ユーザー側に 「serverに提出されたコードだ」ということを条件に conditional compilation を許すためになんかの Cabal flag を定義してもいいのでは,ということになんとなく思い至りました.環境変数 ATCODER = 1 だけだと Conditional compilation には不便なので.
transitive dependency の direct dependency への 格上げの追加提案:
• contravariant
• kan-extensions
• adjunctions
• bifunctors
• comonad
• distributive
• profunctors
• semigroupoids
忘れるところでした:
• strict-lens
滑り込みですが、 trifecta , megaparsec 等々を突っ込むのに賛成が得られるなら
• parser-combinators
もあったほうが良さそう
前回のアップデートで外れていたこの2つは復活させたいです。漏れてるのにそもそも気づいてなかったが
• scientific
• split
transitive dependencyに入っていてよく使われてる tagged も入れてもいいかもです
そう言えば, strict に These 入ってるんだから,
• these
• these-lens
は入れないと整合性がないですね.
まとめます.現在結論が出てないものと出ているっぽいものをごた混ぜにして,現在提案されているパッケージは次の通りです.transitive dependency からの昇格については :arrow_heading_up: で示します:
strict 系:
• :arrow_heading_up: strict
• :new: strict-lens
• :new: strict-containers (?)
• :new: strict-containers-lens (?)
• :new: strict-tuple (?)
パーサ系:
• :new: megaparsec
• :new: trifecta
• :new: parser-combinators
圏論系 (transitive dependency の昇格):
• :arrow_heading_up: contravariant
• :arrow_heading_up: kan-extensions
• :arrow_heading_up: adjunctions
• :arrow_heading_up: bifunctors
• :arrow_heading_up: comonad
• :arrow_heading_up: distributive
• :arrow_heading_up: profunctors
• :arrow_heading_up: semigroupoids
GHC-bundled packages:
• :new: Cabal
• :new: Cabal-syntax
• :arrow_heading_up: binary
• :arrow_heading_up: directory
• :arrow_heading_up: filepath
• :new: ghc
• :new: ghc-boot
• :arrow_heading_up: ghc-boot-th
• :new: ghc-compact
• :new: ghc-heap
• :arrow_heading_up: ghc-prim
• :new: ghci
• :new: haskelline
• :new: hpc
• :new: integer-gmp
• :new: libiserv
• :arrow_heading_up: pretty
• :arrow_heading_up: process
• :arrow_heading_up: stm
• :new: terminfo
• :arrow_heading_up: time
• :arrow_heading_up: unix
• :new: xhtml
その他:
• :arrow_heading_up: these (cf. strict)
• :new: these-lens
• :arrow_heading_up: scientific (前々回の環境からの復活)
• :arrow_heading_up: split (前々回の環境からの復活)
• :arrow_heading_up: tagged
• :arrow_heading_up: indexed-traversable
• :arrow_heading_up: indexed-traversable-instances
パッケージ追加以外の提案:
• Cabal flag atcoder を追加して有効化する
... Replies ...
strict-tuple, strict-containersはhackageでみるとあんまり使われてないのでちょっと不安があります。
実際に使っていくのであれば入れてもいいかなという感じです
... Replies ...
theseのdocを読んでたんですけど、semialignとsemialign-indexedまで入れないと片手落ちだったりしますかね、これ……? (取り敢えず追加提案の期限は過ぎてるので、明示的な賛同が出ない限りは提案はしません)
... Replies ...
圏論系ライブラリは free を入れ忘れてました。transitive dependencyとしては入ってはいるものです
... Replies ...
witherable を入れたいのを今思い出したけど,もうすぐテスト開始時間だし,transitive dependency にも入ってないし,やめといた方がいいかな…
... Replies ...
ここまでの議論で提示されたパッケージでテスト作業を開始します.いくつか変更があるのでご確認ください.
libiserv が bytestring の更新を拒絶する (installed version 以外の使用を許さない)ので除外します.結構なbugfixと速度改善が入ってるっぽいので bytestring 更新 を外すのは惜しい.
ghci も bytestring を拒絶したので除外しましたが,これ ghc 系が軒並み拒絶されそうですね…
compact 系がややこしいですね.これ, ghc-compact が Hackage上で dependency を upgrade されておらず <4.17 になっているから,~GHC git repo の 9.4.4 tag 上でちゃんと <4.18 になっているにもかかわらず~依存性解決に失敗する.その上 compact-0.2.0.0 の deps が base <4.16 なのは本当にわけがわからない!
cabal build --only-dependencies に --upgrade-dependencies をつけているので,これを除外するとどうにかなるかも知れませんが,今回は compact と ghc-compact はともに諦めます.後で Issue でも投げます.
今回諦めたパッケージ:
• compact
• ghc
• ghc-boot
• ghc-compact
• ghci
• libiserv
dependency solver は取り敢えず通ったので,あとはビルド待ちです.
各パッケージに丁寧に lower bound をつけているので, --upgrade-dependencies をやっぱり外すことにしました. compact はもちろん不可能ですが, ghc-compact は回復できました.
... Replies ...
filepath-1.4.100.3 が System.OSPath を Trustworthy にしといてくれなかったので,こいつに directory を介して依存する hpc とincompatibleになってますね… hpc , なんか全module Safe なんですよ…
意見募集: directory を最新版 (`1.3.8.1` ), filepath を 1.4.100.3 にする代わりに hpc を諦めるのと, directory を 1.3.7.1, filepath を 1.4.2.2 にして hpc を入れるのと,どっちが良いと思いますか?
ghc 9.4.4にバンドルされてるのが`directory-1.3.7.1`, filepath-1.4.2.2 なので,最新バージョンを諦めてhpcを入れる方がいいかなと思います
そうかー… というか,`directory` はなんで pre-existing visible module を safe から unsafe に格下げしておいて minor bump なんだろう…
それはそれとして,すでに bytestring を (競プロ的により重要であろうという予断により) 優先して ghc, ghc-boot, ghci libiserv を諦めているので, 何か filepath か directory を優先する 理由があるようであれば hpc を諦めなきゃいけないんですけど,パッと思いつくところにはないですよね?
hpcを入れる理由は最大限対応できそうなものは対応する以上の意味はないですね。 filepathとdirectoryのバージョンに関してはどれでもいいかなと思ってます。競プロ的にはそこまで重要ではないはずです
後から hpc を入れるようにも filepath + directory を最新版にするようにもどっちにも後方互換性を保って対応できるようにするために hpc を除外して directory-1.3.7.1 と filepath-1.4.2.2 を導入しておくみたいなやり方も考えてます…
ghciを諦めているのであればhpcを諦めるのは自然な感じはします。
あと,ghciの依存関係のために入っているhaskeline, terminfo外せるかなと。
directory, filepathのバージョンは依存関係の解決が1番簡単なものがよさそうで,
無難に行くならdirectory-1.3.7.1とfilepath-1.4.2.2になるんですかね
hpc, haskeline, terminfo を 除外して directory >=1.3.7.1 && <1.3.8.0 と filepath >=1.4.2.2 && <1.4.99 にします….
それに伴って unix ^>=2.7.3 になりました
dependency がビルド完了すること, Hello Worldが走ることと, flag が役目を果たすのを一応チェックしました.まだ Imports of Export list を走らせてません. チェックソース生成器に修正が必要なので….license report もまだ作ってないですが,時間が時間なので取り敢えず書いてきます.
ghc-compact の回復はできていませんでした.これも同様に bytestring との conflict です.諦めます.